001/*
002 *  Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.update;
017
018import com.mybatisflex.core.exception.FlexExceptions;
019import com.mybatisflex.core.query.QueryColumn;
020import com.mybatisflex.core.query.QueryCondition;
021import com.mybatisflex.core.query.QueryWrapper;
022import com.mybatisflex.core.util.LambdaGetter;
023import com.mybatisflex.core.util.LambdaUtil;
024import com.mybatisflex.core.util.UpdateEntity;
025import org.apache.ibatis.javassist.util.proxy.Proxy;
026import org.apache.ibatis.javassist.util.proxy.ProxyFactory;
027import org.apache.ibatis.javassist.util.proxy.ProxyObject;
028
029import java.io.Serializable;
030import java.util.Map;
031
032/**
033 * @author michael
034 */
035public interface UpdateWrapper<T> extends PropertySetter<UpdateWrapper<T>>, Serializable {
036
037    default Map<String, Object> getUpdates() {
038        ModifyAttrsRecordHandler handler = null;
039        if (this instanceof ProxyObject) {
040            handler = (ModifyAttrsRecordHandler) ((ProxyObject) this).getHandler();
041        } else if (this instanceof Proxy) {
042            handler = (ModifyAttrsRecordHandler) ProxyFactory.getHandler((Proxy) this);
043        } else {
044            throw FlexExceptions.wrap("获取实体类代理对象 %s 的字段更新处理器时出错,该对象既不是 ProxyObject 的实例,也不是 Proxy 的实例", this.getClass().getName());
045        }
046        return handler.getUpdates();
047    }
048
049    @Override
050    default UpdateWrapper<T> set(String property, Object value, boolean isEffective) {
051        if (isEffective) {
052            if (value instanceof QueryWrapper
053                    || value instanceof QueryColumn
054                    || value instanceof QueryCondition) {
055                getUpdates().put(property, new RawValue(value));
056            } else {
057                getUpdates().put(property, value);
058            }
059        }
060        return this;
061    }
062
063    @Override
064    default UpdateWrapper<T> set(QueryColumn property, Object value, boolean isEffective) {
065        if (isEffective) {
066            if (value instanceof QueryWrapper
067                    || value instanceof QueryColumn
068                    || value instanceof QueryCondition) {
069                getUpdates().put(property.getName(), new RawValue(value));
070            } else {
071                getUpdates().put(property.getName(), value);
072            }
073        }
074        return this;
075    }
076
077    @Override
078    default <E> UpdateWrapper<T> set(LambdaGetter<E> property, Object value, boolean isEffective) {
079        if (isEffective) {
080            if (value instanceof QueryWrapper
081                    || value instanceof QueryColumn
082                    || value instanceof QueryCondition) {
083                getUpdates().put(LambdaUtil.getFieldName(property), new RawValue(value));
084            } else {
085                getUpdates().put(LambdaUtil.getFieldName(property), value);
086            }
087        }
088        return this;
089    }
090
091    @Override
092    default UpdateWrapper<T> setRaw(String property, Object value, boolean isEffective) {
093        if (isEffective) {
094            getUpdates().put(property, new RawValue(value));
095        }
096        return this;
097    }
098
099
100    @Override
101    default UpdateWrapper<T> setRaw(QueryColumn property, Object value, boolean isEffective) {
102        if (isEffective) {
103            getUpdates().put(property.getName(), new RawValue(value));
104        }
105        return this;
106    }
107
108    @Override
109    default <E> UpdateWrapper<T> setRaw(LambdaGetter<E> property, Object value, boolean isEffective) {
110        if (isEffective) {
111            getUpdates().put(LambdaUtil.getFieldName(property), new RawValue(value));
112        }
113        return this;
114    }
115
116
117    static <T> UpdateWrapper<T> of(T entity) {
118        if (entity instanceof UpdateWrapper) {
119            return (UpdateWrapper<T>) entity;
120        } else {
121            return (UpdateWrapper<T>) UpdateEntity.ofNotNull(entity);
122        }
123    }
124
125    static <T> UpdateWrapper<T> of(Class<T> tClass) {
126        return (UpdateWrapper<T>) UpdateEntity.of(tClass);
127    }
128
129
130    default T toEntity() {
131        return (T) this;
132    }
133
134}