All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.chengyuxing.sql.XQLFileManagerConfig Maven / Gradle / Ivy

Go to download

Light wrapper of JDBC, support ddl, dml, query, plsql/procedure/function, transaction and manage sql file.

There is a newer version: 9.0.2
Show newest version
package com.github.chengyuxing.sql;

import com.github.chengyuxing.common.io.FileResource;
import com.github.chengyuxing.common.io.TypedProperties;
import com.github.chengyuxing.common.script.expression.IPipe;
import com.github.chengyuxing.sql.exceptions.YamlDeserializeException;
import com.github.chengyuxing.sql.yaml.FeaturedConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Dynamic SQL File Manager config.
 */
public class XQLFileManagerConfig {
    private static final Logger log = LoggerFactory.getLogger(XQLFileManagerConfig.class);
    // ----------------optional properties------------------
    protected Map files = new LinkedHashMap<>();
    protected Map constants = new HashMap<>();
    protected Map> pipeInstances = new HashMap<>();
    protected Map pipes = new HashMap<>();
    protected String charset = "UTF-8";
    protected String delimiter = ";";
    protected Character namedParamPrefix = ':';
    protected String databaseId;
    // ----------------optional properties------------------
    protected volatile boolean loading;

    /**
     * Constructs a new XQLFileManagerConfig.
     */
    public XQLFileManagerConfig() {
    }

    /**
     * Constructs a new XQLFileManagerConfig with config location.
     *
     * @param configLocation config location path
     */
    public XQLFileManagerConfig(String configLocation) {
        FileResource resource = new FileResource(configLocation);
        if (configLocation.endsWith(".yml")) {
            loadYaml(resource);
            return;
        }
        if (configLocation.endsWith(".properties")) {
            loadProperties(resource);
            return;
        }
        throw new IllegalArgumentException("Not support file type: " + configLocation);
    }

    /**
     * Load yml config.
     *
     * @param yamlLocation yml resource
     */
    public void loadYaml(FileResource yamlLocation) {
        Yaml yaml = new Yaml(new FeaturedConstructor());
        try {
            XQLFileManagerConfig config = yaml.loadAs(yamlLocation.getInputStream(), XQLFileManagerConfig.class);
            if (Objects.isNull(config)) {
                log.warn("yaml loaded nothing, resource length is {}", yamlLocation.getInputStream().available());
                return;
            }
            config.copyStateTo(this);
        } catch (Exception e) {
            throw new YamlDeserializeException("load yaml config error.", e);
        }
    }

    /**
     * Load properties config.
     *
     * @param propertiesLocation properties resource
     */
    public void loadProperties(FileResource propertiesLocation) {
        TypedProperties properties = new TypedProperties();
        try {
            XQLFileManagerConfig config = new XQLFileManagerConfig();
            properties.load(propertiesLocation.getInputStream());
            Map localFiles = new LinkedHashMap<>();
            Map localConstants = new HashMap<>();
            Map localPipes = new HashMap<>();
            properties.forEach((k, s) -> {
                String p = k.toString().trim();
                String v = s.toString().trim();
                if (!p.isEmpty() && !v.isEmpty()) {
                    if (p.startsWith("files.")) {
                        localFiles.put(p.substring(6), v);
                    } else if (p.startsWith("constants.")) {
                        localConstants.put(p.substring(10), v);
                    } else if (p.startsWith("pipes.")) {
                        localPipes.put(p.substring(6), v);
                    }
                }
            });

            config.setFiles(localFiles);
            config.setConstants(localConstants);
            config.setPipes(localPipes);
            config.setDelimiter(properties.getProperty("delimiter"));
            config.setCharset(properties.getProperty("charset"));
            config.setNamedParamPrefix(properties.getProperty("namedParamPrefix", ":").charAt(0));
            config.setDatabaseId(properties.getProperty("databaseId"));
            config.copyStateTo(this);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    /**
     * Copy config state to another.
     *
     * @param other another XQLFileManagerConfig
     */
    public void copyStateTo(XQLFileManagerConfig other) {
        Field[] fields = XQLFileManagerConfig.class.getDeclaredFields();
        for (Field field : fields) {
            if (!Modifier.isFinal(field.getModifiers())) {
                field.setAccessible(true);
                try {
                    Object v = field.get(this);
                    if (Objects.nonNull(v)) {
                        field.set(other, v);
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Failed to copy XQLFileManagerConfig state: " + e.getMessage(), e);
                }
            }
        }
    }

    /**
     * If XQL file manager on loading while config state changing by another thread, throws exception.
     */
    void checkLoading() {
        if (loading) throw new ConcurrentModificationException("Cannot set property while loading.");
    }

    /**
     * Loading state.
     *
     * @return true if loading or false
     */
    public boolean isLoading() {
        return loading;
    }

    /**
     * Get sql files map.
     *
     * @return file map [alias, file name]
     */
    public Map getFiles() {
        return files;
    }

    /**
     * Set sql files map.
     *
     * @param files files map [alias, file name]
     */
    public void setFiles(Map files) {
        checkLoading();
        if (Objects.nonNull(files)) {
            this.files = new LinkedHashMap<>(files);
        }
    }

    /**
     * Get constants map.
     *
     * @return constants map
     */
    public Map getConstants() {
        return constants;
    }

    /**
     * Set constants map.
* Example: *

constants:

*
*
{db: "test"}
*
*

sql statement:

*
*
select ${db}.user from table
*
*

result:

*
*
select test.user from table
*
* * @param constants constants map */ public void setConstants(Map constants) { checkLoading(); if (Objects.nonNull(constants)) { this.constants = new HashMap<>(constants); } } /** * Get custom pipe instances map. * * @return custom pipe instances map */ public Map> getPipeInstances() { return pipeInstances; } /** * Set custom pipe instances map. * * @param pipeInstances custom pipe instances map [pipe name, pipe instance] */ public void setPipeInstances(Map> pipeInstances) { checkLoading(); if (Objects.nonNull(pipeInstances)) { this.pipeInstances = new HashMap<>(pipeInstances); } } /** * Get custom pipe class name map. * * @return custom pipe class name map */ public Map getPipes() { return pipes; } /** * Set custom pipe class name map. * * @param pipes custom pipe class name map [pipe name, pipe class name] * @see IPipe */ public void setPipes(Map pipes) { checkLoading(); if (Objects.nonNull(pipes)) { this.pipes = new HashMap<>(pipes); } } /** * Get sql file parsing charset. * * @return charset name */ public String getCharset() { return charset; } /** * Set sql file parsing charset, UTF-8 is default. * * @param charset charset * @see StandardCharsets */ public void setCharset(String charset) { checkLoading(); if (Objects.nonNull(charset)) { this.charset = charset; } } /** * Set sql file parsing charset, UTF-8 is default. * * @param charset charset * @see StandardCharsets */ public void setCharset(Charset charset) { checkLoading(); if (Objects.nonNull(charset)) { this.charset = charset.name(); } } /** * Get delimiter of multi sql fragment/template, symbol ({@code ;}) is default. * * @return delimiter */ public String getDelimiter() { return delimiter; } /** * Set delimiter of multi sql fragment/template, symbol ({@code ;}) is default.
* Sometimes default delimiter is not enough, such as one procedure body or plsql maybe contains * more than one sql statement which ends with {@code ;}, for correct set to other is necessary, like {@code ;;} . * * @param delimiter multi sql fragment/template delimiter */ public void setDelimiter(String delimiter) { checkLoading(); if (Objects.nonNull(delimiter) && !delimiter.trim().isEmpty()) { this.delimiter = delimiter; } } /** * Get named parameter prefix. * * @return named parameter prefix */ public Character getNamedParamPrefix() { return namedParamPrefix; } /** * Set named parameter prefix. (for IDEA Rabbit-SQL plugin) * * @param namedParamPrefix named parameter prefix */ public void setNamedParamPrefix(Character namedParamPrefix) { checkLoading(); if (Objects.nonNull(namedParamPrefix) && namedParamPrefix != ' ') { this.namedParamPrefix = namedParamPrefix; } } /** * Get database name. * * @return database name */ public String getDatabaseId() { return databaseId; } /** * Set database name. * * @param databaseId database name */ public void setDatabaseId(String databaseId) { checkLoading(); this.databaseId = databaseId; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof XQLFileManagerConfig)) return false; XQLFileManagerConfig config = (XQLFileManagerConfig) o; if (!getFiles().equals(config.getFiles())) return false; if (!getConstants().equals(config.getConstants())) return false; if (!getPipeInstances().equals(config.getPipeInstances())) return false; if (!getPipes().equals(config.getPipes())) return false; if (!getCharset().equals(config.getCharset())) return false; if (!getDelimiter().equals(config.getDelimiter())) return false; if (!getNamedParamPrefix().equals(config.getNamedParamPrefix())) return false; return getDatabaseId() != null ? getDatabaseId().equals(config.getDatabaseId()) : config.getDatabaseId() == null; } @Override public int hashCode() { int result = getFiles().hashCode(); result = 31 * result + getConstants().hashCode(); result = 31 * result + getPipeInstances().hashCode(); result = 31 * result + getPipes().hashCode(); result = 31 * result + getCharset().hashCode(); result = 31 * result + getDelimiter().hashCode(); result = 31 * result + getNamedParamPrefix().hashCode(); result = 31 * result + (getDatabaseId() != null ? getDatabaseId().hashCode() : 0); return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy