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.dialect;
017
018import com.mybatisflex.core.constant.SqlConsts;
019import com.mybatisflex.core.util.StringUtil;
020
021import java.util.Collections;
022import java.util.Set;
023
024/**
025 * 用于对数据库的关键字包装
026 */
027public class KeywordWrap {
028
029    /**
030     * 无反义处理, 适用于 db2, informix, clickhouse 等
031     */
032    public static final KeywordWrap NONE = new KeywordWrap("", "") {
033        @Override
034        public String wrap(String keyword) {
035            return keyword;
036        }
037    };
038
039    /**
040     * 无反义区分大小写处理, 适用于 db2, informix, clickhouse 等
041     */
042    public static final KeywordWrap NONE_CASE_SENSITIVE = new KeywordWrap(true, "", "") {
043        @Override
044        public String wrap(String keyword) {
045            return keyword;
046        }
047    };
048
049    /**
050     * 反引号反义处理, 适用于 mysql, h2 等
051     */
052    public static final KeywordWrap BACK_QUOTE = new KeywordWrap("`", "`");
053
054    /**
055     * 双引号反义处理, 适用于 postgresql, sqlite, derby, oracle 等
056     */
057    public static final KeywordWrap DOUBLE_QUOTATION = new KeywordWrap("\"", "\"");
058
059    /**
060     * 方括号反义处理, 适用于 sqlserver
061     */
062    public static final KeywordWrap SQUARE_BRACKETS = new KeywordWrap("[", "]");
063    /**
064     * 大小写敏感
065     */
066    private boolean caseSensitive = false;
067
068    /**
069     * 自动把关键字转换为大写
070     */
071    private boolean keywordsToUpperCase = false;
072    /**
073     * 数据库关键字
074     */
075    private final Set<String> keywords;
076    /**
077     * 前缀
078     */
079    private final String prefix;
080    /**
081     * 后缀
082     */
083    private final String suffix;
084
085
086    public KeywordWrap(String prefix, String suffix) {
087        this(false, Collections.emptySet(), prefix, suffix);
088    }
089
090    public KeywordWrap(boolean caseSensitive, String prefix, String suffix) {
091        this(caseSensitive, Collections.emptySet(), prefix, suffix);
092    }
093
094    public KeywordWrap(Set<String> keywords, String prefix, String suffix) {
095        this(false, keywords, prefix, suffix);
096    }
097
098    public KeywordWrap(boolean caseSensitive, Set<String> keywords, String prefix, String suffix) {
099        this.caseSensitive = caseSensitive;
100        this.keywords = keywords;
101        this.prefix = prefix;
102        this.suffix = suffix;
103    }
104
105    public KeywordWrap(boolean caseSensitive, boolean keywordsToUpperCase, Set<String> keywords, String prefix,
106        String suffix) {
107        this.caseSensitive = caseSensitive;
108        this.keywordsToUpperCase = keywordsToUpperCase;
109        this.keywords = keywords;
110        this.prefix = prefix;
111        this.suffix = suffix;
112    }
113
114    public String wrap(String keyword) {
115        if (StringUtil.isBlank(keyword) || SqlConsts.ASTERISK.equals(keyword.trim())) {
116            return keyword;
117        }
118
119        if (caseSensitive || keywords.isEmpty()) {
120            return prefix + keyword + suffix;
121        }
122
123        keyword = keywordsToUpperCase ? keyword.toUpperCase() : keyword;
124        return keywords.contains(keyword) ? (prefix + keyword + suffix) : keyword;
125    }
126
127    public boolean isCaseSensitive() {
128        return caseSensitive;
129    }
130
131    public void setCaseSensitive(boolean caseSensitive) {
132        this.caseSensitive = caseSensitive;
133    }
134
135    public boolean isKeywordsToUpperCase() {
136        return keywordsToUpperCase;
137    }
138
139    public void setKeywordsToUpperCase(boolean keywordsToUpperCase) {
140        this.keywordsToUpperCase = keywordsToUpperCase;
141    }
142
143    public Set<String> getKeywords() {
144        return keywords;
145    }
146
147    public String getPrefix() {
148        return prefix;
149    }
150
151    public String getSuffix() {
152        return suffix;
153    }
154}