001/*
002 *  Copyright (c) 2022-2024, 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.query;
017
018import com.mybatisflex.core.constant.SqlOperator;
019import com.mybatisflex.core.util.LambdaGetter;
020import com.mybatisflex.core.util.LambdaUtil;
021
022import java.util.HashMap;
023
024/**
025 * <p>SQL 操作符集合,用于为多个字段分别设置操作符。
026 *
027 * <p>该类继承自 {@link HashMap},其中键是<strong>数据库字段的名称</strong>,
028 * 值是对应的 {@link SqlOperator} 枚举实例。
029 *
030 * @author michael
031 * @author 王帅
032 * @see SqlOperator
033 */
034public class SqlOperators extends HashMap<String, SqlOperator> {
035
036    /**
037     * 一个空的实例,用于表示没有操作符的情况。
038     */
039    private static final SqlOperators EMPTY = new SqlOperators() {
040        @Override
041        public SqlOperator put(String key, SqlOperator value) {
042            throw new IllegalArgumentException("不能为 \"empty\" SqlOperators 设置 SqlOperator");
043        }
044    };
045
046    /**
047     * 默认构造函数。
048     * 创建一个空的 {@link SqlOperators} 实例。
049     */
050    public SqlOperators() {
051    }
052
053    /**
054     * <p>带初始容量的构造函数。
055     *
056     * <p>创建一个具有指定初始容量的 {@link SqlOperators} 实例。
057     *
058     * @param initialCapacity 初始容量
059     */
060    public SqlOperators(int initialCapacity) {
061        super(initialCapacity);
062    }
063
064    /**
065     * <p>复制构造函数。
066     *
067     * <p>创建一个包含指定 {@link SqlOperators} 实例所有元素的新的 {@link SqlOperators} 实例。
068     *
069     * @param sqlOperators 要复制的 {@link SqlOperators} 实例
070     */
071    public SqlOperators(SqlOperators sqlOperators) {
072        this.putAll(sqlOperators);
073    }
074
075    /**
076     * <p>获取一个空的 {@link SqlOperators} 实例。
077     *
078     * <p><strong>注意:空实例不允许向其中添加任何操作符。</strong>
079     *
080     * @return 一个空的、不可操作的 {@link SqlOperators} 实例
081     */
082    public static SqlOperators empty() {
083        return EMPTY;
084    }
085
086    /**
087     * 创建一个新的 {@link SqlOperators} 实例。
088     *
089     * @return 一个新的、可操作的 {@link SqlOperators} 实例
090     */
091    public static SqlOperators of() {
092        return new SqlOperators();
093    }
094
095    /**
096     * 使用给定数据库的字段名称和操作符创建一个新的 {@link SqlOperators} 实例。
097     *
098     * @param columnName 数据库的字段名称
099     * @param operator   对应的字段操作符
100     * @return 包含指定字段和操作符的 {@link SqlOperators} 实例
101     */
102    public static SqlOperators of(String columnName, SqlOperator operator) {
103        return new SqlOperators(1).set(columnName, operator);
104    }
105
106    /**
107     * 使用给定的查询列({@link QueryColumn})和操作符创建一个新的 {@link SqlOperators} 实例。
108     *
109     * @param column   查询列
110     * @param operator 对应的字段操作符
111     * @return 包含指定字段和操作符的 {@link SqlOperators} 实例
112     */
113    public static SqlOperators of(QueryColumn column, SqlOperator operator) {
114        return new SqlOperators(1).set(column, operator);
115    }
116
117    /**
118     * 使用给定的 Lambda 表达式和操作符创建一个新的 {@link SqlOperators} 实例。
119     *
120     * @param getter   Lambda 表达式
121     * @param operator 对应的字段操作符
122     * @param <T>      实体类的类型。
123     * @return 包含指定字段和操作符的 {@link SqlOperators} 实例
124     */
125    public static <T> SqlOperators of(LambdaGetter<T> getter, SqlOperator operator) {
126        return new SqlOperators(1).set(getter, operator);
127    }
128
129    /**
130     * 设置数据库的字段名称以及对应的操作符。
131     *
132     * @param columnName 字段名称
133     * @param operator   字段操作符
134     * @return 当前 {@link SqlOperators} 实例,以便进行链式调用
135     */
136    public SqlOperators set(String columnName, SqlOperator operator) {
137        this.put(columnName, operator);
138        return this;
139    }
140
141    /**
142     * 设置查询列({@link QueryColumn})对应数据库字段的操作符。
143     *
144     * @param column   查询列
145     * @param operator 操作符
146     * @return 当前 {@link SqlOperators} 实例,以便进行链式调用
147     */
148    public SqlOperators set(QueryColumn column, SqlOperator operator) {
149        return set(column.getName(), operator);
150    }
151
152    /**
153     * 设置 Lambda 表达式对应数据库字段的操作符。
154     *
155     * @param getter   Lambda 表达式
156     * @param operator 对应的操作符
157     * @param <T>      实体类的类型
158     * @return 当前 {@link SqlOperators} 实例,以便进行链式调用
159     */
160    public <T> SqlOperators set(LambdaGetter<T> getter, SqlOperator operator) {
161        return set(LambdaUtil.getQueryColumn(getter), operator);
162    }
163
164}