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

com.hundsun.lightdb.unisql.golang.Transformer Maven / Gradle / Ivy

package com.hundsun.lightdb.unisql.golang;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hundsun.lightdb.unisql.model.TableMeta;
import com.hundsun.lightdb.unisql.model.UnisqlProperties;

import java.util.List;

import jnr.ffi.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;

/**
 * @Author yupeishi
 * @Date 2023/11/20
 **/

@Slf4j
public class Transformer {

    private static final String IGNORE_TRANS = "/*skipTransform*/";

    private static final boolean DEBUG;
    public static final boolean IS_COMPARE;

    public static final ThreadLocal VARIABLE_PARAMETER_THREAD_LOCAL;


    static {
        final UnisqlProperties properties = UnisqlProperties.getInstance();
        final int maxSize = properties.getCacheMaximumSize();
        final int expireSeconds = properties.getCacheExpireSeconds();
        DEBUG = properties.isDebug();
        // 可变参数初始化
        VARIABLE_PARAMETER_THREAD_LOCAL = new ThreadLocal() {
            /**
             * ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值
             */
            @Override
            protected VariableParameter initialValue() {
                return VariableParameter.builder().restoreFmt(0L).build();
            }
        };
        // 全局静态参数初始化
        GlobalStaticParameter globalStaticParameter = new GlobalStaticParameter();
        if (properties.isSkip()) {
            globalStaticParameter.setGlobalSkip(1);
        }
        if (properties.isMysqlBackslashEscapes()){
            globalStaticParameter.setMysqlBackslashEscapes(1);
        }
        if (properties.isErrorSkip()) {
            globalStaticParameter.setGlobalErrorSkip(1);
        }
        if (properties.isOpenCache()) {
            globalStaticParameter.setIsCache(1);
            globalStaticParameter.setCacheMaximumSize(maxSize);
            globalStaticParameter.setCacheExpireSeconds(expireSeconds);
        }
        long goGc = properties.getGOGC();
        globalStaticParameter.setGoGc(goGc);
        long goMemLimit = properties.getGOMEMLIMIT();
        globalStaticParameter.setGoMemLimit(goMemLimit);
        if(DEBUG){
            globalStaticParameter.setUniSqlDebugLog(1);
        }
        if (StringUtils.isNotBlank(properties.getCompareServerUrl())) {
            IS_COMPARE = true;
            globalStaticParameter.setCompareServerUrl(properties.getCompareServerUrl());
        } else {
            IS_COMPARE = false;
        }
        // 设置统一SQL自定义函数脚本执行所在的schema或database; 默认unisql
        if (StringUtils.isNotBlank(properties.getSchema())) {
            globalStaticParameter.setSchema(properties.getSchema());
        }

        if (StringUtils.isNotBlank(String.valueOf(properties.getRemoveDoublequoted()))) {
            globalStaticParameter.setRemoveDoubleQuoted(properties.getRemoveDoublequoted());
        }
        if (StringUtils.isNotBlank(properties.getDecodeParametersFuncNames())) {
            globalStaticParameter.setDecodeParametersFuncNames(properties.getDecodeParametersFuncNames());
        }
        if (StringUtils.isNotBlank(properties.getMoveTablespaceReplaceSql())) {
            globalStaticParameter.setMoveTablespaceReplaceSql(properties.getMoveTablespaceReplaceSql());
        }

        /*设置是否将create database换成create schema*/
        if (StringUtils.isNotBlank(String.valueOf(properties.getDefaultChangeDatabaseToSchema()))) {
            globalStaticParameter.setChangeDatabaseToSchema(properties.getDefaultChangeDatabaseToSchema());
        }
        /*换后的sql中自定义表或字段名称结尾是否使用随机数0不随机,1随机 默认1随机*/
        globalStaticParameter.setTableOrColumnNameRandom(properties.isTableOrColumnNameRandom());
        /*oracle源端是否使用反引号转为双引号 0不转 1转 默认0不转*/
        globalStaticParameter.setChangeBackQuotesToDoubleQuotes(properties.isChangeBackQuotesToDoubleQuotes());
        /*配置关键字,对象名如果匹配到了此配置参数中配置的关键字则使用双引号包裹,每个关键字之间用逗号分隔*/
        if (StringUtils.isNotBlank(properties.getKeywordDoubleQuotes())) {
            globalStaticParameter.setKeywordDoubleQuotes(properties.getKeywordDoubleQuotes());
        }

        // 初始化配置参数,配置参数会覆盖go中的配置参数
        IGoParser parser = GoParserFactory.getGoParser();
        ObjectMapper jsonMapper = new ObjectMapper();
        try {
            // 设置全局静态参数
            String globalJson = jsonMapper.writeValueAsString(globalStaticParameter);
            parser.SetGlobalStaticParameter(globalJson);
            if (DEBUG) {
                if (log.isDebugEnabled()) {
                    log.debug("[UNISQL][GlobalStaticParameter] {}", globalJson);
                }
            }
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("Java calls GO global static parameters conversion json failed,Use default values!", e);
            }
        }

    }

    public static String parse(String sql, String source, String target) {
        try {
            return parse(sql, source, target, VARIABLE_PARAMETER_THREAD_LOCAL.get());
        } finally {
            VARIABLE_PARAMETER_THREAD_LOCAL.remove();
        }

    }

    public static String parse(String sql, String source, String target, VariableParameter variableParameter) {

        ReturnParameter returnParameter = parsePro(sql, source, target, variableParameter);
        // todo
        if (!SqlState.SUCCESS.getState().equals(returnParameter.getState())) {
            throw new IllegalStateException(String.format("SQLSTATE[%s]-ERROR: %s \nSource SQL: [ %s ]",
                    returnParameter.getState(), returnParameter.getMessage(), sql));
        }
        return returnParameter.getTargetSql();
    }

    /**
     * java中缓存迁移至GO模块中统一管理,此方法已废弃
     */
    @Deprecated
    public static ReturnParameter parseUseCache(String sql, String source, String target, boolean useCache) {
         return parseUseCache(sql, source, target, useCache, VariableParameter.builder().restoreFmt(0L).build());
    }

    /**
     * java中缓存迁移至GO模块中统一管理,此方法已废弃
     */
    @Deprecated
    public static ReturnParameter parseUseCache(String sql, String source, String target, boolean useCache,
                                       VariableParameter variableParameter) {
        IGoParser parser = GoParserFactory.getGoParser();

        variableParameter.setSourceSql(sql);
        variableParameter.setSourceDialect(source);
        variableParameter.setTargetDialect(target);

        ObjectMapper jsonMapper = new ObjectMapper();
        String jsonParameter;
        try {
            // Java调用GO相关参数转换为JSON字符串
            jsonParameter = jsonMapper.writeValueAsString(variableParameter);
            if (DEBUG) {
                if (log.isDebugEnabled()) {
                    log.debug("[UNISQL][VariableParameter] {}", jsonParameter);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("Java calls GO related variable parameters conversion json failed!");
        }

        Pointer p4 = parser.TransformPro(jsonParameter);
        try {
            String utf8 = p4.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
            ReturnParameter returnParameter = null;
            try {
                returnParameter = jsonMapper.readValue(utf8, ReturnParameter.class);

            } catch (Exception e) {
                throw new IllegalStateException(String.format("json failed to parse into ReturnParameter! [%s]", utf8));
            }

            return returnParameter;
        } finally {
            parser.FreePointer(p4);
        }
    }

    private static ReturnParameter parsePro(String sql, String source, String target,
                                           VariableParameter variableParameter) {
        IGoParser parser = GoParserFactory.getGoParser();

        variableParameter.setSourceSql(sql);
        variableParameter.setSourceDialect(source);
        variableParameter.setTargetDialect(target);

        ObjectMapper jsonMapper = new ObjectMapper();
        String jsonParameter;
        try {
            // Java调用GO相关参数转换为JSON字符串
            jsonParameter = jsonMapper.writeValueAsString(variableParameter);
            if (DEBUG) {
                if (log.isDebugEnabled()) {
                    log.debug("[UNISQL][VariableParameter] {}", jsonParameter);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("Java calls GO related variable parameters conversion json failed!");
        }

        Pointer p4 = parser.TransformPro(jsonParameter);
        try {
            String utf8 = p4.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
            ReturnParameter returnParameter = null;
            try {
                returnParameter = jsonMapper.readValue(utf8, ReturnParameter.class);

            } catch (Exception e) {
                throw new IllegalStateException(String.format("json failed to parse into ReturnParameter! [%s]", utf8));
            }

            return returnParameter;
        } finally {
            parser.FreePointer(p4);
        }
    }

    /**
     * 根据DML 获取执行前的DQL和执行后的DQL
     */
    public static ReturnParameter getDqlByDml(VariableParameter variableParameter) {
        IGoParser parser = GoParserFactory.getGoParser();

        ObjectMapper jsonMapper = new ObjectMapper();
        String jsonParameter;
        try {
            jsonParameter = jsonMapper.writeValueAsString(variableParameter);
            if (DEBUG) {
                if (log.isDebugEnabled()) {
                    log.debug("[GetDqlByDml][VariableParameter] {}", jsonParameter);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("Java calls GO related variable parameters conversion json failed!");
        }

        Pointer p = parser.GetDqlByDml(jsonParameter);
        try {
            String utf8 = p.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
            ReturnParameter returnParameter = null;
            try {
                returnParameter = jsonMapper.readValue(utf8, ReturnParameter.class);

            } catch (Exception e) {
                throw new IllegalStateException(String.format("json failed to parse into ReturnParameter! [%s]", utf8));
            }

            return returnParameter;
        } finally {
            parser.FreePointer(p);
        }
    }

    /**
     * 初始化表元数据
     */
    public static ReturnParameter initTableMetas(List tableMetas) {

        ObjectMapper jsonMapper = new ObjectMapper();
        String jsonParameter;
        try {
            jsonParameter = jsonMapper.writeValueAsString(tableMetas);
            if (DEBUG) {
                if (log.isDebugEnabled()) {
                    log.debug("[initTableMetas][VariableParameter] {}", jsonParameter);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("Java calls GO related variable parameters conversion json failed!");
        }

        return initTableMetas(jsonMapper, jsonParameter);
    }

    /**
     * 初始化表元数据
     */
    public static ReturnParameter initTableMetas(String jsonTableMetas) {

        return initTableMetas(new ObjectMapper(),jsonTableMetas);
    }

    /**
     * 初始化表元数据
     */
    private static ReturnParameter initTableMetas(ObjectMapper jsonMapper, String jsonTableMetas) {
        IGoParser parser = GoParserFactory.getGoParser();
        Pointer p = parser.InitTableMetas(jsonTableMetas);
        try {
            String utf8 = p.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
            ReturnParameter returnParameter = null;
            try {
                returnParameter = jsonMapper.readValue(utf8, ReturnParameter.class);

            } catch (Exception e) {
                throw new IllegalStateException(String.format("json failed to parse into ReturnParameter! [%s]", utf8));
            }

            return returnParameter;
        } finally {
            parser.FreePointer(p);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy