Search in sources :

Example 1 with MySqlRenameTableStatement

use of com.shulie.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement in project LinkAgent by shulieTech.

the class SqlParser method parseAndReplaceTableNames.

public static String parseAndReplaceTableNames(String sql, String key, String dbTypeName, String midType) throws SQLException {
    sql = sql.replaceAll("<  >", "<>");
    DbType dbType = DbType.of(dbTypeName);
    Map<String, String> mappingTable = getMappingTables(key);
    if (SqlParser.lowerCase != null && "Y".equals(SqlParser.lowerCase)) {
        Map<String, String> mappingTableLower = new ConcurrentHashMap<String, String>();
        Set<String> keys = mappingTable.keySet();
        for (String tableName : keys) {
            String value = mappingTable.get(tableName);
            mappingTableLower.put(tableName.toLowerCase(), value.toLowerCase());
        }
        mappingTable = mappingTableLower;
        resetMappingTables(key, mappingTableLower);
    }
    // new MySQL Parser
    SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbTypeName);
    if (parser == null) {
        if (GlobalConfig.getInstance().getWrongSqlDetail().size() < 10) {
            GlobalConfig.getInstance().addWrongSqlDetail(StringUtils.substring("dbType not support" + key + " dbType" + dbTypeName + " sql" + sql, 0, 1995));
        }
        throw new SQLException("dbType not support" + key + " dbType" + dbTypeName + " sql" + sql);
    }
    // 使用Parser解析生成AST,这里SQLStatement就是AST
    final StringWriter val = new StringWriter();
    try {
        final List<SQLStatement> sqlStatements = parser.parseStatementList();
        for (final SQLStatement sqlStatement : sqlStatements) {
            SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(val, dbType);
            SchemaStatVisitor visitor2 = SQLUtils.createSchemaStatVisitor(dbType);
            sqlStatement.accept(visitor2);
            final Map<TableStat.Name, TableStat> map2 = visitor2.getTables();
            // Set<String> tablesName = visitor.getTables();
            final Map<String, String> additionalTableNames = new HashMap();
            for (final TableStat.Name name : map2.keySet()) {
                /**
                 * 过滤掉函数
                 */
                String tableName = name.getName();
                if (StringUtils.indexOf(tableName, '(') != -1 && StringUtils.indexOf(tableName, ')') != -1) {
                    continue;
                }
                for (String mappingName : mappingTable.keySet()) {
                    mappingName = StringUtils.replace(mappingName, "\"", "");
                    String nameTemp = name.getName();
                    String schema = "";
                    String fullTableName = StringUtils.replace(nameTemp, "\"", "");
                    if (nameTemp != null && StringUtils.contains(nameTemp, ".")) {
                        schema = StringUtils.substringBefore(nameTemp, ".");
                        nameTemp = StringUtils.substringAfter(nameTemp, ".");
                    }
                    if (StringUtils.indexOf(schema, "\"") != -1) {
                        schema = StringUtils.replace(schema, "\"", "");
                    }
                    if (StringUtils.indexOf(nameTemp, "\"") != -1) {
                        nameTemp = StringUtils.replace(nameTemp, "\"", "");
                    }
                    /**
                     * 如果配置的表名与获取到的表名相等,则如果 sql 中有 schema,则将映射表名也添加 schema
                     *   如sql 中的表名为 user或者是 test.user,但是配置的表名为 user
                     *
                     * 如果sql中的表名(带 schema)与映射表名相等,则直接添加映射表名
                     *
                     *   如 sql 中的表名为 test.user,配置的表名也为 test.user
                     */
                    if (StringUtils.equalsIgnoreCase(nameTemp, mappingName)) {
                        String value = mappingTable.get(mappingName);
                        if (StringUtils.isNotBlank(schema)) {
                            additionalTableNames.put(schema + "." + nameTemp, schema + "." + value);
                        } else {
                            additionalTableNames.put(nameTemp, value);
                        }
                    } else if (StringUtils.equalsIgnoreCase(fullTableName, mappingName)) {
                        additionalTableNames.put(fullTableName, mappingName);
                    }
                }
            }
            if (additionalTableNames.size() > 0) {
                mappingTable.putAll(additionalTableNames);
            }
            visitor.setTableMapping(mappingTable);
            sqlStatement.accept(visitor);
        }
    } catch (Throwable e) {
        if (GlobalConfig.getInstance().getWrongSqlDetail().size() < 10) {
            GlobalConfig.getInstance().addWrongSqlDetail(StringUtils.substring(("Exception:" + e + " sql" + sql), 0, 1995));
        }
        throw new SQLException("Wrong sql:" + sql, e);
    }
    SQLStatementParser parser2 = SQLParserUtils.createSQLStatementParser(val.toString(), dbTypeName);
    final List<SQLStatement> sqlStatements2 = parser2.parseStatementList();
    for (final SQLStatement sqlStatement : sqlStatements2) {
        if (sqlStatement instanceof SQLInsertStatement || sqlStatement instanceof SQLUpdateStatement || sqlStatement instanceof SQLDeleteStatement || sqlStatement instanceof SQLAlterTableStatement || sqlStatement instanceof SQLDropTableStatement || sqlStatement instanceof SQLCreateTableStatement || sqlStatement instanceof MySqlRenameTableStatement) {
            SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
            sqlStatement.accept(visitor);
            final Map<TableStat.Name, TableStat> map = visitor.getTables();
            for (final TableStat.Name name : map.keySet()) {
                boolean passThisTable = false;
                String nameTemp = SQLUtils.normalize(name.getName(), dbType);
                if (nameTemp != null && StringUtils.contains(nameTemp, ".")) {
                    nameTemp = StringUtils.substringAfter(nameTemp, ".");
                }
                if ("DUAL".equalsIgnoreCase(nameTemp)) {
                    // dual table no need pt table
                    passThisTable = true;
                } else {
                    for (final String mappingname : mappingTable.values()) {
                        if (StringUtils.equalsIgnoreCase(nameTemp, mappingname)) {
                            passThisTable = true;
                        }
                    }
                }
                if (!passThisTable) {
                    if (GlobalConfig.getInstance().getWrongSqlDetail().size() < 10) {
                        GlobalConfig.getInstance().addWrongSqlDetail(StringUtils.substring(sql, 0, 1995));
                    }
                    String url = key;
                    if (url.indexOf('|') != -1) {
                        url = url.substring(0, url.indexOf('|'));
                    }
                    int idx = key.lastIndexOf('|');
                    String userName = idx > 0 ? key.substring(idx + 1) : "未知";
                    ErrorReporter.buildError().setErrorType(ErrorTypeEnum.DataSource).setErrorCode("datasource-0004").setMessage(String.format("没有配置对应的影子表! url:%s, table:%s, driverClassName:%s, dbType:%s, userName:%s, 中间件类型:%s", url, name.getName(), getDriverClassName(url), dbType, userName, midType)).setDetail(String.format("The business table [%s] doesn't has shadow mapping table! url:%s, table:%s, " + "driverClassName:%s, dbType:%s, [sql] %s [new sql] %s", name.getName(), url, name.getName(), getDriverClassName(url), dbType, sql, val)).closePradar(ConfigNames.SHADOW_DATABASE_CONFIGS).report();
                    throw new SQLException(String.format("The business table [%s] doesn't has shadow mapping table! url:%s, table:%s, " + "driverClassName:%s, dbType:%s, username:%s, 中间件类型:%s, [sql] %s [new sql] %s", name.getName(), url, name.getName(), getDriverClassName(url), dbType, userName, midType, sql, val));
                }
            }
        }
    }
    return val.toString();
}
Also used : SQLException(java.sql.SQLException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TableStat(com.shulie.druid.stat.TableStat) SQLStatement(com.shulie.druid.sql.ast.SQLStatement) StringWriter(java.io.StringWriter) SQLASTOutputVisitor(com.shulie.druid.sql.visitor.SQLASTOutputVisitor) MySqlRenameTableStatement(com.shulie.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SchemaStatVisitor(com.shulie.druid.sql.visitor.SchemaStatVisitor) SQLStatementParser(com.shulie.druid.sql.parser.SQLStatementParser) DbType(com.shulie.druid.DbType)

Aggregations

DbType (com.shulie.druid.DbType)1 SQLStatement (com.shulie.druid.sql.ast.SQLStatement)1 MySqlRenameTableStatement (com.shulie.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement)1 SQLStatementParser (com.shulie.druid.sql.parser.SQLStatementParser)1 SQLASTOutputVisitor (com.shulie.druid.sql.visitor.SQLASTOutputVisitor)1 SchemaStatVisitor (com.shulie.druid.sql.visitor.SchemaStatVisitor)1 TableStat (com.shulie.druid.stat.TableStat)1 StringWriter (java.io.StringWriter)1 SQLException (java.sql.SQLException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1