001package gudusoft.gsqlparser.dlineage.dataflow.metadata.sqlenv; 002 003import gudusoft.gsqlparser.EDbVendor; 004import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataAnalyzer; 005import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager; 006import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*; 007import gudusoft.gsqlparser.dlineage.util.Pair3; 008import gudusoft.gsqlparser.sqlenv.*; 009import gudusoft.gsqlparser.util.SQLUtil; 010 011import java.util.*; 012 013public class SQLEnvMetadataAnalyzer implements MetadataAnalyzer<TSQLEnv> { 014 015 private Map<String, procedure> procedureMap = new LinkedHashMap<String, procedure>(); 016 private Map<String, table> tableMap = new LinkedHashMap<String, table>(); 017 private Map<String, oraclePackage> oraclePackageMap = new LinkedHashMap<String, oraclePackage>(); 018 private Map<String, column> columnMap = new LinkedHashMap<String, column>(); 019 private EDbVendor vendor; 020 private boolean lower = false; 021 022 public SQLEnvMetadataAnalyzer(boolean lower) { 023 this.lower = lower; 024 } 025 026 @Override 027 public synchronized dataflow analyzeMetadata(EDbVendor metadataVendor, TSQLEnv sqlenv) { 028 init(vendor); 029 dataflow dataflow = new dataflow(); 030 031 String serverName = sqlenv.getDefaultServerName(); 032 EDbVendor vendor = metadataVendor; 033 if (sqlenv.getDBVendor() != null) { 034 vendor = sqlenv.getDBVendor(); 035 } 036 037 boolean supportsCatalogs = TSQLEnv.supportCatalog(vendor); 038 boolean supportsSchemas = TSQLEnv.supportSchema(vendor); 039 040 List<TSQLCatalog> databases = sqlenv.getCatalogList(); 041 if (databases != null) { 042 for (int i = 0; i < databases.size(); i++) { 043 TSQLCatalog catalog = databases.get(i); 044 String databaseName = catalog.getName(); 045 if (SQLUtil.parseNames(databaseName).size() > 1) { 046 databaseName = "\"" + databaseName + "\""; 047 } 048 List<TSQLSchema> schemas = catalog.getSchemaList(); 049 if (schemas == null) { 050 continue; 051 } 052 for (int j = 0; j < schemas.size(); j++) { 053 TSQLSchema jsonSchema = schemas.get(j); 054 String schemaName = (String) jsonSchema.getName(); 055 if (SQLUtil.parseNames(schemaName).size() > 1) { 056 schemaName = "\"" + schemaName + "\""; 057 } 058 List<TSQLSchemaObject> dbObjs = jsonSchema.getSchemaObjectList(); 059 if (dbObjs == null) { 060 continue; 061 } 062 for (int k = 0; k < dbObjs.size(); k++) { 063 TSQLSchemaObject jsonTable = dbObjs.get(k); 064 if (jsonTable instanceof TSQLTable) { 065 TSQLTable table = (TSQLTable) jsonTable; 066 String tableName = table.getName(); 067 boolean isView = table.isView(); 068 List<TSQLColumn> columns = table.getColumnList(); 069 if (columns == null) { 070 continue; 071 } 072 for (int l = 0; l < columns.size(); l++) { 073 TSQLColumn jsonColumn = columns.get(l); 074 String columnName = jsonColumn.getName(); 075 if (SQLUtil.isEmpty(columnName)) { 076 continue; 077 } 078 appendTable(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, tableName, isView, columnName); 079 } 080 } 081 if (jsonTable instanceof TSQLOraclePackage) { 082 TSQLOraclePackage sqlOraclePackage = (TSQLOraclePackage) jsonTable; 083 oraclePackage oraclePackage = appendOraclePackage(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, sqlOraclePackage); 084 if (sqlOraclePackage.getSchemaObjectList() != null) { 085 for (TSQLSchemaObject sqlProcedure : sqlOraclePackage.getSchemaObjectList()) { 086 appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, (TSQLSchemaObject) sqlProcedure, oraclePackage); 087 } 088 } 089 } 090 if(jsonTable instanceof TSQLProcedure){ 091 appendProcedure(vendor, supportsCatalogs, supportsSchemas, dataflow, serverName, databaseName, schemaName, (TSQLSchemaObject)jsonTable, null); 092 } 093 } 094 } 095 } 096 } 097 sortTableColumns(dataflow); 098 return dataflow; 099 } 100 101 private void appendProcedure(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, TSQLSchemaObject sqlProcedure, oraclePackage oraclePackage) { 102 String procedureName = sqlProcedure.getName(); 103 String procedureKey = getFullName(serverName, databaseName, schemaName, procedureName); 104 if (!procedureMap.containsKey(procedureKey)) { 105 procedure procedure = new procedure(); 106 if (serverName != null && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(serverName)) { 107 procedure.setServer(serverName); 108 } 109 if(supportsCatalogs && supportsSchemas){ 110 if(databaseName != null && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(databaseName)) { 111 if (lower) { 112 procedure.setDatabase(SQLUtil.trimColumnStringQuote(databaseName).toLowerCase()); 113 } else { 114 procedure.setDatabase(databaseName); 115 } 116 } 117 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 118 if (lower) { 119 procedure.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 120 } else { 121 procedure.setSchema(schemaName); 122 } 123 } 124 } 125 else if(supportsCatalogs){ 126 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 127 if (lower) { 128 procedure.setDatabase(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 129 } else { 130 procedure.setDatabase(schemaName); 131 } 132 } 133 } 134 else if(supportsSchemas){ 135 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 136 if (lower) { 137 procedure.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 138 } else { 139 procedure.setSchema(schemaName); 140 } 141 } 142 } 143 144 if (lower) { 145 procedure.setName(SQLUtil.trimColumnStringQuote(procedureName).toLowerCase()); 146 } else { 147 procedure.setName(procedureName); 148 } 149 if (supportsSchemas && !SQLUtil.isEmpty(procedure.getSchema()) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(procedure.getSchema())) { 150 procedure.setName(procedure.getSchema() + "." + procedure.getName()); 151 } 152 if (supportsCatalogs && !SQLUtil.isEmpty(procedure.getDatabase()) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(procedure.getDatabase())) { 153 procedure.setName(procedure.getDatabase() + "." + procedure.getName()); 154 } 155 procedure.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID)); 156 if (ModelBindingManager.getGlobalSqlInfo() != null) { 157 procedure.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L, 158 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + "," 159 + new Pair3<Long, Long, Integer>(-1L, -1L, 160 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash()))); 161 } 162 procedure.setType(sqlProcedure.getDataObjectType().name().replace("dot","").toLowerCase()); 163 if(oraclePackage!=null) { 164 oraclePackage.getProcedures().add(procedure); 165 } 166 else{ 167 dataflow.getProcedures().add(procedure); 168 } 169 procedureMap.put(procedureKey, procedure); 170 } 171 } 172 173 private oraclePackage appendOraclePackage(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, TSQLOraclePackage sqlOraclePackage) { 174 String oraclePackageName = sqlOraclePackage.getName(); 175 String oraclePackageKey = getFullName(serverName, databaseName, schemaName, oraclePackageName); 176 if (!oraclePackageMap.containsKey(oraclePackageKey)) { 177 oraclePackage oraclePackage = new oraclePackage(); 178 if (serverName != null && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(serverName)) { 179 oraclePackage.setServer(serverName); 180 } 181 if(supportsCatalogs && supportsSchemas){ 182 if(databaseName != null && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(databaseName)) { 183 if (lower) { 184 oraclePackage.setDatabase(SQLUtil.trimColumnStringQuote(databaseName).toLowerCase()); 185 } else { 186 oraclePackage.setDatabase(databaseName); 187 } 188 } 189 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 190 if (lower) { 191 oraclePackage.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 192 } else { 193 oraclePackage.setSchema(schemaName); 194 } 195 } 196 } 197 else if(supportsCatalogs){ 198 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 199 if (lower) { 200 oraclePackage.setDatabase(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 201 } else { 202 oraclePackage.setDatabase(schemaName); 203 } 204 } 205 } 206 else if(supportsSchemas){ 207 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 208 if (lower) { 209 oraclePackage.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 210 } else { 211 oraclePackage.setSchema(schemaName); 212 } 213 } 214 } 215 216 if (lower) { 217 oraclePackage.setName(SQLUtil.trimColumnStringQuote(oraclePackageName).toLowerCase()); 218 } else { 219 oraclePackage.setName(oraclePackageName); 220 } 221 if (supportsSchemas && !SQLUtil.isEmpty(oraclePackage.getSchema()) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(oraclePackage.getSchema())) { 222 oraclePackage.setName(oraclePackage.getSchema() + "." + oraclePackage.getName()); 223 } 224 if (supportsCatalogs && !SQLUtil.isEmpty(oraclePackage.getDatabase()) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(oraclePackage.getDatabase())) { 225 oraclePackage.setName(oraclePackage.getDatabase() + "." + oraclePackage.getName()); 226 } 227 oraclePackage.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID)); 228 if (ModelBindingManager.getGlobalSqlInfo() != null) { 229 oraclePackage.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L, 230 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + "," 231 + new Pair3<Long, Long, Integer>(-1L, -1L, 232 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash()))); 233 } 234 dataflow.getPackages().add(oraclePackage); 235 oraclePackageMap.put(oraclePackageKey, oraclePackage); 236 } 237 return oraclePackageMap.get(oraclePackageKey); 238 } 239 240 private void init(EDbVendor vendor) { 241 this.vendor = vendor; 242 procedureMap.clear(); 243 tableMap.clear(); 244 columnMap.clear(); 245 if (ModelBindingManager.get() == null) { 246 ModelBindingManager.set(new ModelBindingManager()); 247 } 248 } 249 250 private void sortTableColumns(dataflow dataflow) { 251 if (dataflow.getTables() != null) { 252 for (table table : dataflow.getTables()) { 253 Collections.sort(table.getColumns(), new Comparator<column>() { 254 public int compare(column t1, column t2) { 255 if (t1.getName().equalsIgnoreCase("RelationRows")) 256 return 1; 257 if (t2.getName().equalsIgnoreCase("RelationRows")) 258 return -1; 259 return 0; 260 } 261 }); 262 } 263 } 264 265 if (dataflow.getResultsets() != null) { 266 for (table table : dataflow.getResultsets()) { 267 Collections.sort(table.getColumns(), new Comparator<column>() { 268 public int compare(column t1, column t2) { 269 if (t1.getName().equalsIgnoreCase("RelationRows")) 270 return 1; 271 if (t2.getName().equalsIgnoreCase("RelationRows")) 272 return -1; 273 return 0; 274 } 275 }); 276 } 277 } 278 } 279 280 private void appendTable(EDbVendor vendor, boolean supportsCatalogs, boolean supportsSchemas, dataflow dataflow, String serverName, String databaseName, String schemaName, String tableName, 281 boolean isView, String columnName) { 282 String tableKey = getFullName(serverName, databaseName, schemaName, tableName); 283 if (!tableMap.containsKey(tableKey)) { 284 table table = new table(); 285 if (serverName != null && !TSQLEnv.DEFAULT_SERVER_NAME.equalsIgnoreCase(serverName)) { 286 table.setServer(serverName); 287 } 288 if(supportsCatalogs && supportsSchemas){ 289 if(databaseName != null && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(databaseName)) { 290 if (lower) { 291 table.setDatabase(SQLUtil.trimColumnStringQuote(databaseName).toLowerCase()); 292 } else { 293 table.setDatabase(databaseName); 294 } 295 } 296 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 297 if (lower) { 298 table.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 299 } else { 300 table.setSchema(schemaName); 301 } 302 } 303 } 304 else if(supportsCatalogs){ 305 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 306 if (lower) { 307 table.setDatabase(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 308 } else { 309 table.setDatabase(schemaName); 310 } 311 } 312 } 313 else if(supportsSchemas){ 314 if(schemaName != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(schemaName)) { 315 if (lower) { 316 table.setSchema(SQLUtil.trimColumnStringQuote(schemaName).toLowerCase()); 317 } else { 318 table.setSchema(schemaName); 319 } 320 } 321 } 322 323 if (lower) { 324 table.setName(SQLUtil.trimColumnStringQuote(tableName).toLowerCase()); 325 } else { 326 table.setName(tableName); 327 } 328 if (supportsSchemas && !SQLUtil.isEmpty(table.getSchema()) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(table.getSchema())) { 329 table.setName(table.getSchema() + "." + table.getName()); 330 } 331 if (supportsCatalogs && !SQLUtil.isEmpty(table.getDatabase()) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(table.getDatabase())) { 332 table.setName(table.getDatabase() + "." + table.getName()); 333 } 334 table.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID)); 335 if (ModelBindingManager.getGlobalSqlInfo() != null) { 336 table.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L, 337 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + "," 338 + new Pair3<Long, Long, Integer>(-1L, -1L, 339 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash()))); 340 } 341 if (isView) { 342 table.setType("view"); 343 dataflow.getViews().add(table); 344 } else { 345 table.setType("table"); 346 dataflow.getTables().add(table); 347 } 348 tableMap.put(tableKey, table); 349 } 350 351 table table = tableMap.get(tableKey); 352 String sourceColumnKey = getFullName(serverName, databaseName, schemaName, tableName, columnName); 353 if (!columnMap.containsKey(sourceColumnKey)) { 354 column column = new column(); 355 column.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID)); 356 column.setName(columnName); 357 if ("RelationRows".equalsIgnoreCase(columnName)) { 358 column.setSource("system"); 359 } 360 if (ModelBindingManager.getGlobalSqlInfo() != null) { 361 column.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L, 362 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + "," 363 + new Pair3<Long, Long, Integer>(-1L, -1L, 364 ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash()))); 365 } 366 table.getColumns().add(column); 367 columnMap.put(sourceColumnKey, column); 368 } 369 } 370 371 private String getFullName(String... segments) { 372 StringBuilder builder = new StringBuilder(); 373 for (int i = 0; i < segments.length; i++) { 374 builder.append(segments[i]); 375 if (i < segments.length - 1) { 376 builder.append("."); 377 } 378 } 379 return builder.toString(); 380 } 381}