001package gudusoft.gsqlparser.dlineage.dataflow.model; 002 003import gudusoft.gsqlparser.EDbVendor; 004import gudusoft.gsqlparser.ESqlStatementType; 005import gudusoft.gsqlparser.TCustomSqlStatement; 006import gudusoft.gsqlparser.TSourceToken; 007import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 008import gudusoft.gsqlparser.dlineage.util.Pair3; 009import gudusoft.gsqlparser.nodes.TFunctionCall; 010import gudusoft.gsqlparser.nodes.TObjectName; 011import gudusoft.gsqlparser.nodes.TParseTreeNode; 012import gudusoft.gsqlparser.sqlenv.TSQLEnv; 013import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 014import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure; 015import gudusoft.gsqlparser.util.Logger; 016import gudusoft.gsqlparser.util.LoggerFactory; 017import gudusoft.gsqlparser.util.SQLUtil; 018 019import java.io.ByteArrayInputStream; 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.List; 023import java.util.Properties; 024 025public class Procedure { 026 private static final Logger logger = LoggerFactory.getLogger(Procedure.class); 027 private long id; 028 private String server; 029 private String database; 030 private String schema; 031 private String name; 032 private String fullName; 033 private Pair3<Long, Long, String> startPosition; 034 private Pair3<Long, Long, String> endPosition; 035 private List<Argument> arguments = new ArrayList<Argument>(); 036 private ESqlStatementType type; 037 private TParseTreeNode procedureObject; 038 private OraclePackage parentPackage; 039 040 public Procedure(TStoredProcedureSqlStatement procedure) { 041 if (procedure == null) { 042 throw new IllegalArgumentException("Procedure arguments can't be null."); 043 } else { 044 this.id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 045 this.procedureObject = procedure; 046 TObjectName procedureName = getProcedureName(); 047 TSourceToken startToken = procedure.getStartToken(); 048 TSourceToken endToken = procedure.getEndToken(); 049 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 050 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 051 endToken.columnNo + (long) SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash()); 052 this.fullName = procedureName.toString(); 053 this.name = procedureName.toString(); 054 055 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 056 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 057 boolean supportSchema = TSQLEnv.supportSchema(vendor); 058 059 fillSchemaInfo(); 060 061 if (supportCatalog) { 062 this.database = DlineageUtil.getTableDatabase(procedureName.toString()); 063 if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 064 && !SQLUtil.isEmpty(procedureName.getImplictDatabaseString())) { 065 this.database = procedureName.getImplictDatabaseString(); 066 } 067 } 068 069 if (supportSchema) { 070 this.schema = DlineageUtil.getTableSchema(procedureName.toString()); 071 if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 072 && !SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 073 this.schema = procedureName.getImplictSchemaString(); 074 } 075 076 if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) { 077 if (!SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 078 this.schema = procedureName.getImplictSchemaString(); 079 } else { 080 this.schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 081 } 082 } 083 } 084 085 086 if (!supportCatalog) { 087 this.database = null; 088 } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) { 089 this.database = getDefaultDatabase(); 090 } 091 092 if (!supportSchema) { 093 this.schema = null; 094 } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) { 095 this.schema = getDefaultSchema(); 096 } 097 098 updateProcedureName(supportCatalog, supportSchema); 099 100 this.type = procedure.sqlstatementtype; 101 102 if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) { 103 this.server = getDefaultServer(); 104 } 105 } 106 } 107 108 public Procedure(TObjectName procedureName) { 109 if (procedureName == null) { 110 throw new IllegalArgumentException("Procedure arguments can't be null."); 111 } else { 112 this.id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 113 this.procedureObject = procedureName; 114 TSourceToken startToken = procedureName.getStartToken(); 115 TSourceToken endToken = procedureName.getEndToken(); 116 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 117 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 118 endToken.columnNo + (long) SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash()); 119 this.fullName = procedureName.toString(); 120 this.name = procedureName.toString(); 121 122 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 123 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 124 boolean supportSchema = TSQLEnv.supportSchema(vendor); 125 126 fillSchemaInfo(); 127 128 if (supportCatalog) { 129 this.database = DlineageUtil.getTableDatabase(procedureName.toString()); 130 if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 131 && !SQLUtil.isEmpty(procedureName.getImplictDatabaseString())) { 132 this.database = procedureName.getImplictDatabaseString(); 133 } 134 } 135 136 if (supportSchema) { 137 this.schema = DlineageUtil.getTableSchema(procedureName.toString()); 138 if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 139 && !SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 140 this.schema = procedureName.getImplictSchemaString(); 141 } 142 143 if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) { 144 if (!SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 145 this.schema = procedureName.getImplictSchemaString(); 146 } else { 147 this.schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 148 } 149 } 150 } 151 152 if (!supportCatalog) { 153 this.database = null; 154 } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) { 155 this.database = getDefaultDatabase(); 156 } 157 158 if (!supportSchema) { 159 this.schema = null; 160 } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) { 161 this.schema = getDefaultSchema(); 162 } 163 164 updateProcedureName(supportCatalog, supportSchema); 165 166 if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) { 167 this.server = getDefaultServer(); 168 } 169 } 170 } 171 172 public Procedure(TFunctionCall function) { 173 if (function == null) { 174 throw new IllegalArgumentException("Procedure arguments can't be null."); 175 } else { 176 this.id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 177 this.procedureObject = function; 178 TObjectName procedureName = getProcedureName(); 179 TSourceToken startToken = procedureName.getStartToken(); 180 TSourceToken endToken = procedureName.getEndToken(); 181 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 182 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 183 endToken.columnNo + (long) SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash()); 184 this.fullName = procedureName.toString(); 185 this.name = procedureName.toString(); 186 187 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 188 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 189 boolean supportSchema = TSQLEnv.supportSchema(vendor); 190 191 fillSchemaInfo(); 192 193 if (supportCatalog) { 194 this.database = DlineageUtil.getTableDatabase(procedureName.toString()); 195 if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 196 && !SQLUtil.isEmpty(procedureName.getImplictDatabaseString())) { 197 this.database = procedureName.getImplictDatabaseString(); 198 } 199 } 200 201 if (supportSchema) { 202 this.schema = DlineageUtil.getTableSchema(procedureName.toString()); 203 if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 204 && !SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 205 this.schema = procedureName.getImplictSchemaString(); 206 } 207 208 if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) { 209 if (!SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 210 this.schema = procedureName.getImplictSchemaString(); 211 } else { 212 this.schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 213 } 214 } 215 } 216 217 if (!supportCatalog) { 218 this.database = null; 219 } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) { 220 this.database = getDefaultDatabase(); 221 } 222 223 if (!supportSchema) { 224 this.schema = null; 225 } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) { 226 this.schema = getDefaultSchema(); 227 } 228 229 updateProcedureName(supportCatalog, supportSchema); 230 231 if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) { 232 this.server = getDefaultServer(); 233 } 234 } 235 } 236 237 private void fillSchemaInfo() { 238 TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek()); 239 String sqlComment = null; 240 try { 241 sqlComment = stmt.getCommentBeforeNode(); 242 } catch (Exception e) { 243 } 244 if (!SQLUtil.isEmpty(sqlComment) && (sqlComment.indexOf("db") != -1 || sqlComment.indexOf("schema") != -1)) { 245 Properties properties = new Properties(); 246 try { 247 properties.load( 248 new ByteArrayInputStream(sqlComment.replace("--", "").trim().replace(",", "\n").getBytes())); 249 if (SQLUtil.isEmpty(this.server) && properties.containsKey("db-instance")) { 250 this.server = properties.getProperty("db-instance"); 251 } 252 if (SQLUtil.isEmpty(this.database) && properties.containsKey("db")) { 253 this.database = properties.getProperty("db"); 254 if(this.database.indexOf(".")!=-1) { 255 String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor()); 256 this.database = delimitedChar + SQLUtil.trimColumnStringQuote(this.database) + delimitedChar; 257 } 258 } 259 if (SQLUtil.isEmpty(this.schema) && properties.containsKey("schema")) { 260 this.schema = properties.getProperty("schema"); 261 if(this.schema.indexOf(".")!=-1) { 262 String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor()); 263 this.schema = delimitedChar + SQLUtil.trimColumnStringQuote(this.schema) + delimitedChar; 264 } 265 } 266 } catch (IOException e) { 267 logger.error("load sql comment properties failed.", e); 268 } 269 } 270 } 271 272 protected void updateProcedureName(boolean supportCatalog, boolean supportSchema) { 273 List<String> segments = SQLUtil.parseNames(this.name); 274 this.name = segments.get(segments.size() - 1); 275 if (supportCatalog && supportSchema) { 276 StringBuilder builder = new StringBuilder(); 277 if (segments.size() > 2) { 278 builder.append(segments.get(segments.size() - 3)).append("."); 279 } else { 280 if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) { 281 builder.append(this.database).append("."); 282 } 283 } 284 if (segments.size() > 1) { 285 builder.append(segments.get(segments.size() - 2)).append("."); 286 } else { 287 if (builder.length() > 0) { 288 if (this.schema == null) { 289 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 290 this.schema = "dbo"; 291 } else { 292 this.schema = getDefaultSchema(); 293 } 294 } 295 else if (TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema) 296 && ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 297 this.schema = "dbo"; 298 } 299 builder.append(this.schema).append("."); 300 } else { 301 if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) { 302 builder.append(this.schema).append("."); 303 } 304 } 305 } 306 builder.append(this.name); 307 this.name = builder.toString(); 308 } else if (supportCatalog) { 309 if (segments.size() > 1) { 310 this.name = segments.get(segments.size() - 2) + "." + this.name; 311 } 312 else { 313 if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) { 314 this.name = this.database + "." + this.name; 315 } 316 } 317 } else if (supportSchema) { 318 if (segments.size() > 1) { 319 this.name = segments.get(segments.size() - 2) + "." + this.name; 320 } else { 321 if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) { 322 this.name = this.schema + "." + this.name; 323 } 324 } 325 } 326 } 327 328 protected String getDefaultServer() { 329 String defaultServer = null; 330 if (ModelBindingManager.getGlobalSQLEnv() != null) { 331 defaultServer = ModelBindingManager.getGlobalSQLEnv().getDefaultServerName(); 332 } 333 if (!SQLUtil.isEmpty(defaultServer)) 334 return defaultServer; 335 return TSQLEnv.DEFAULT_SERVER_NAME; 336 } 337 338 protected String getDefaultSchema() { 339 String defaultSchema = null; 340 if (ModelBindingManager.getGlobalSQLEnv() != null) { 341 defaultSchema = ModelBindingManager.getGlobalSQLEnv().getDefaultSchemaName(); 342 } 343 if (!SQLUtil.isEmpty(defaultSchema)) 344 return defaultSchema; 345 return TSQLEnv.DEFAULT_SCHEMA_NAME; 346 } 347 348 protected String getDefaultDatabase() { 349 String defaultDatabase = null; 350 if (ModelBindingManager.getGlobalSQLEnv() != null) { 351 defaultDatabase = ModelBindingManager.getGlobalSQLEnv().getDefaultCatalogName(); 352 } 353 if (!SQLUtil.isEmpty(defaultDatabase)) 354 return defaultDatabase; 355 return TSQLEnv.DEFAULT_DB_NAME; 356 } 357 358 private TObjectName getProcedureName() { 359 if (procedureObject instanceof TTeradataCreateProcedure) { 360 return ((TTeradataCreateProcedure) procedureObject).getProcedureName(); 361 } 362 if (procedureObject instanceof TStoredProcedureSqlStatement) { 363 return ((TStoredProcedureSqlStatement) procedureObject).getStoredProcedureName(); 364 } 365 if (procedureObject instanceof TFunctionCall) { 366 return ((TFunctionCall) procedureObject).getFunctionName(); 367 } 368 return null; 369 } 370 371 public long getId() { 372 return this.id; 373 } 374 375 public String getName() { 376 return this.name; 377 } 378 379 public void setName(String name) { 380 this.name = name; 381 } 382 383 public Pair3<Long, Long, String> getStartPosition() { 384 return this.startPosition; 385 } 386 387 public Pair3<Long, Long, String> getEndPosition() { 388 return this.endPosition; 389 } 390 391 public String getFullName() { 392 return this.fullName; 393 } 394 395 public void setFullName(String fullName) { 396 this.fullName = fullName; 397 } 398 399 public List<Argument> getArguments() { 400 return this.arguments; 401 } 402 403 public void setArguments(List<Argument> arguments) { 404 this.arguments = arguments; 405 } 406 407 public void addArgument(Argument argument) { 408 if (argument != null && !this.arguments.contains(argument)) { 409 this.arguments.add(argument); 410 } 411 412 } 413 414 public ESqlStatementType getType() { 415 return this.type; 416 } 417 418 public void setType(ESqlStatementType type) { 419 this.type = type; 420 } 421 422 public TParseTreeNode getProcedureObject() { 423 return this.procedureObject; 424 } 425 426 public void setProcedureObject(TParseTreeNode procedureObject) { 427 this.procedureObject = procedureObject; 428 } 429 430 public void setId(int id) { 431 this.id = id; 432 } 433 434 public void setStartPosition(Pair3<Long, Long, String> startPosition) { 435 this.startPosition = startPosition; 436 } 437 438 public void setEndPosition(Pair3<Long, Long, String> endPosition) { 439 this.endPosition = endPosition; 440 } 441 442 public String getDatabase() { 443 return database; 444 } 445 446 public String getSchema() { 447 return schema; 448 } 449 450 public OraclePackage getParentPackage() { 451 return parentPackage; 452 } 453 454 public void setParentPackage(OraclePackage parentPackage) { 455 this.parentPackage = parentPackage; 456 } 457 458 public String getServer() { 459 return server; 460 } 461}