001/*
002 *  Copyright (c) 2022-2023, 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.query.QueryColumn;
019import com.mybatisflex.core.query.QueryCondition;
020import com.mybatisflex.core.query.QueryWrapper;
021import com.mybatisflex.core.util.LambdaGetter;
022import com.mybatisflex.core.util.LambdaUtil;
023import com.mybatisflex.core.util.UpdateEntity;
024import org.apache.ibatis.javassist.util.proxy.ProxyObject;
025
026import java.io.Serializable;
027import java.util.Map;
028
029/**
030 * @author michael
031 */
032public interface UpdateWrapper<T> extends PropertySetter<UpdateWrapper<T>>, Serializable {
033
034    default Map<String, Object> getUpdates() {
035        ModifyAttrsRecordHandler handler = (ModifyAttrsRecordHandler) ((ProxyObject) this).getHandler();
036        return handler.getUpdates();
037    }
038
039    @Override
040    default UpdateWrapper<T> set(String property, Object value, boolean isEffective) {
041        if (isEffective) {
042            if (value instanceof QueryWrapper
043                    || value instanceof QueryColumn
044                    || value instanceof QueryCondition) {
045                getUpdates().put(property, new RawValue(value));
046            } else {
047                getUpdates().put(property, value);
048            }
049        }
050        return this;
051    }
052
053    @Override
054    default UpdateWrapper<T> set(QueryColumn property, Object value, boolean isEffective) {
055        if (isEffective) {
056            if (value instanceof QueryWrapper
057                    || value instanceof QueryColumn
058                    || value instanceof QueryCondition) {
059                getUpdates().put(property.getName(), new RawValue(value));
060            } else {
061                getUpdates().put(property.getName(), value);
062            }
063        }
064        return this;
065    }
066
067    @Override
068    default <E> UpdateWrapper<T> set(LambdaGetter<E> property, Object value, boolean isEffective) {
069        if (isEffective) {
070            if (value instanceof QueryWrapper
071                    || value instanceof QueryColumn
072                    || value instanceof QueryCondition) {
073                getUpdates().put(LambdaUtil.getFieldName(property), new RawValue(value));
074            } else {
075                getUpdates().put(LambdaUtil.getFieldName(property), value);
076            }
077        }
078        return this;
079    }
080
081    @Override
082    default UpdateWrapper<T> setRaw(String property, Object value, boolean isEffective) {
083        if (isEffective) {
084            getUpdates().put(property, new RawValue(value));
085        }
086        return this;
087    }
088
089
090    @Override
091    default UpdateWrapper<T> setRaw(QueryColumn property, Object value, boolean isEffective) {
092        if (isEffective) {
093            getUpdates().put(property.getName(), new RawValue(value));
094        }
095        return this;
096    }
097
098    @Override
099    default <E> UpdateWrapper<T> setRaw(LambdaGetter<E> property, Object value, boolean isEffective) {
100        if (isEffective) {
101            getUpdates().put(LambdaUtil.getFieldName(property), new RawValue(value));
102        }
103        return this;
104    }
105
106
107    static <T> UpdateWrapper<T> of(T entity) {
108        if (entity instanceof UpdateWrapper) {
109            return (UpdateWrapper<T>) entity;
110        } else {
111            return (UpdateWrapper<T>) UpdateEntity.ofNotNull(entity);
112        }
113    }
114
115    static <T> UpdateWrapper<T> of(Class<T> tClass) {
116        return (UpdateWrapper<T>) UpdateEntity.of(tClass);
117    }
118
119
120    default T toEntity() {
121        return (T) this;
122    }
123
124}