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