001package gudusoft.gsqlparser.dlineage.dataflow.model; 002 003import gudusoft.gsqlparser.dlineage.routine.RoutineAliasKey; 004import gudusoft.gsqlparser.EDbVendor; 005import gudusoft.gsqlparser.ESqlStatementType; 006import gudusoft.gsqlparser.TCustomSqlStatement; 007import gudusoft.gsqlparser.TSourceToken; 008import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 009import gudusoft.gsqlparser.dlineage.util.Pair3; 010import gudusoft.gsqlparser.nodes.TFunctionCall; 011import gudusoft.gsqlparser.nodes.TObjectName; 012import gudusoft.gsqlparser.nodes.TParseTreeNode; 013import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 014import gudusoft.gsqlparser.sqlenv.TSQLEnv; 015import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 016import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure; 017import gudusoft.gsqlparser.util.Logger; 018import gudusoft.gsqlparser.util.LoggerFactory; 019import gudusoft.gsqlparser.util.SQLUtil; 020 021import java.io.ByteArrayInputStream; 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.List; 025import java.util.Properties; 026 027public class OraclePackage { 028 private static final Logger logger = LoggerFactory.getLogger(OraclePackage.class); 029 private long id; 030 private String server; 031 private String database; 032 private String schema; 033 private String name; 034 private String fullName; 035 private Pair3<Long, Long, String> startPosition; 036 private Pair3<Long, Long, String> endPosition; 037 private List<Argument> arguments = new ArrayList<Argument>(); 038 private List<Procedure> procedures = new ArrayList<Procedure>(); 039 private ESqlStatementType type; 040 private TParseTreeNode procedureObject; 041 042 public OraclePackage(TStoredProcedureSqlStatement procedure) { 043 if (procedure == null) { 044 throw new IllegalArgumentException("Procedure arguments can't be null."); 045 } else { 046 this.id = ++ModelBindingManager.get().TABLE_COLUMN_ID; 047 this.procedureObject = procedure; 048 TObjectName procedureName = getPackageName(); 049 TSourceToken startToken = procedureName.getStartToken(); 050 TSourceToken endToken = procedureName.getEndToken(); 051 this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo, ModelBindingManager.getGlobalHash()); 052 this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, 053 endToken.columnNo + (long) SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash()); 054 this.fullName = procedureName.toString(); 055 this.name = procedureName.toString(); 056 057 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 058 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 059 boolean supportSchema = TSQLEnv.supportSchema(vendor); 060 061 fillSchemaInfo(); 062 063 if(supportCatalog) { 064 this.database = DlineageUtil.getTableDatabase(procedureName.toString()); 065 if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 066 && !SQLUtil.isEmpty(procedureName.getImplictDatabaseString())) { 067 this.database = procedureName.getImplictDatabaseString(); 068 } 069 } 070 071 if(supportSchema) { 072 this.schema = DlineageUtil.getTableSchema(procedureName.toString()); 073 if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema() 074 && !SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 075 this.schema = procedureName.getImplictSchemaString(); 076 } 077 078 if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) { 079 if (!SQLUtil.isEmpty(procedureName.getImplictSchemaString())) { 080 this.schema = procedureName.getImplictSchemaString(); 081 } else { 082 this.schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 083 } 084 } 085 } 086 087 if (!supportCatalog) { 088 this.database = null; 089 } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) { 090 this.database = getDefaultDatabase(); 091 } 092 093 if (!supportSchema) { 094 this.schema = null; 095 } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) { 096 this.schema = getDefaultSchema(); 097 } 098 099 updatePackageName(supportCatalog, supportSchema); 100 101 this.type = procedure.sqlstatementtype; 102 103 if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) { 104 this.server = getDefaultServer(); 105 } 106 } 107 } 108 109 protected void updatePackageName(boolean supportCatalog, boolean supportSchema) { 110 List<String> segments = SQLUtil.parseNames(this.name); 111 this.name = segments.get(segments.size() - 1); 112 // The typed key of the display name composed below, level for level (RoutineAliasKey.Display). 113 RoutineAliasKey.Display display; 114 try { 115 display = new RoutineAliasKey.Display(getPackageName(), segments); 116 } catch (RuntimeException failure) { 117 display = null; 118 } 119 if (supportCatalog && supportSchema) { 120 StringBuilder builder = new StringBuilder(); 121 if (segments.size() > 2) { 122 builder.append(segments.get(segments.size() - 3)).append("."); 123 if (display != null) display.segment(segments.size() - 3); 124 } else { 125 if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) { 126 builder.append(this.database).append("."); 127 if (display != null) display.field(this.database); 128 } 129 } 130 if (segments.size() > 1) { 131 builder.append(segments.get(segments.size() - 2)).append("."); 132 if (display != null) display.segment(segments.size() - 2); 133 } else { 134 if (builder.length() > 0) { 135 if (this.schema == null) { 136 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 137 this.schema = "dbo"; 138 } else { 139 this.schema = getDefaultSchema(); 140 } 141 } 142 else if (TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema) 143 && ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 144 this.schema = "dbo"; 145 } 146 builder.append(this.schema).append("."); 147 if (display != null) display.field(this.schema); 148 } else { 149 if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) { 150 builder.append(this.schema).append("."); 151 if (display != null) display.field(this.schema); 152 } 153 } 154 } 155 builder.append(this.name); 156 this.name = builder.toString(); 157 } else if (supportCatalog) { 158 if (segments.size() > 1) { 159 this.name = segments.get(segments.size() - 2) + "." + this.name; 160 if (display != null) display.segment(segments.size() - 2); 161 } 162 else { 163 if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) { 164 this.name = this.database + "." + this.name; 165 if (display != null) display.field(this.database); 166 } 167 } 168 } else if (supportSchema) { 169 if (segments.size() > 1) { 170 this.name = segments.get(segments.size() - 2) + "." + this.name; 171 if (display != null) display.segment(segments.size() - 2); 172 } else { 173 if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) { 174 this.name = this.schema + "." + this.name; 175 if (display != null) display.field(this.schema); 176 } 177 } 178 } 179 if (display != null) { 180 try { 181 aliasKey = display.finish(); 182 } catch (RuntimeException failure) { 183 aliasKey = null; 184 } 185 } 186 } 187 188 private void fillSchemaInfo() { 189 TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek()); 190 String sqlComment = null; 191 try { 192 sqlComment = stmt.getCommentBeforeNode(); 193 } catch (Exception e) { 194 } 195 if (!SQLUtil.isEmpty(sqlComment) && (sqlComment.indexOf("db") != -1 || sqlComment.indexOf("schema") != -1)) { 196 Properties properties = new Properties(); 197 try { 198 properties.load( 199 new ByteArrayInputStream(sqlComment.replace("--", "").trim().replace(",", "\n").getBytes())); 200 if (SQLUtil.isEmpty(this.server) && properties.containsKey("db-instance")) { 201 this.server = properties.getProperty("db-instance"); 202 } 203 if (SQLUtil.isEmpty(this.database) && properties.containsKey("db")) { 204 this.database = properties.getProperty("db"); 205 if(this.database.indexOf(".")!=-1) { 206 this.database = SQLUtil.quoteDottedName(ModelBindingManager.getGlobalOption().getVendor(), ESQLDataObjectType.dotCatalog, this.database); 207 } 208 } 209 if (SQLUtil.isEmpty(this.schema) && properties.containsKey("schema")) { 210 this.schema = properties.getProperty("schema"); 211 if(this.schema.indexOf(".")!=-1) { 212 this.schema = SQLUtil.quoteDottedName(ModelBindingManager.getGlobalOption().getVendor(), ESQLDataObjectType.dotSchema, this.schema); 213 } 214 } 215 } catch (IOException e) { 216 logger.error("load sql comment properties failed.", e); 217 } 218 } 219 } 220 221 protected String getDefaultServer() { 222 String defaultServer = null; 223 if (ModelBindingManager.getGlobalSQLEnv() != null) { 224 defaultServer = ModelBindingManager.getGlobalSQLEnv().getDefaultServerName(); 225 } 226 if (!SQLUtil.isEmpty(defaultServer)) 227 return defaultServer; 228 return TSQLEnv.DEFAULT_SERVER_NAME; 229 } 230 231 protected String getDefaultSchema() { 232 return ModelBindingManager.getEffectiveDefaultSchema(); 233 } 234 235 protected String getDefaultDatabase() { 236 return ModelBindingManager.getEffectiveDefaultDatabase(); 237 } 238 239 private TObjectName getPackageName() { 240 if(procedureObject instanceof TTeradataCreateProcedure) 241 { 242 return ((TTeradataCreateProcedure)procedureObject).getProcedureName(); 243 } 244 if(procedureObject instanceof TStoredProcedureSqlStatement) 245 { 246 return ((TStoredProcedureSqlStatement)procedureObject).getStoredProcedureName(); 247 } 248 if(procedureObject instanceof TFunctionCall) 249 { 250 return ((TFunctionCall)procedureObject).getFunctionName(); 251 } 252 return null; 253 } 254 255 public long getId() { 256 return this.id; 257 } 258 259 /** 260 * The typed key of {@link #getName()}, the display name the routine index is keyed by (see 261 * {@code RoutineAliasKey.Display}); null when it cannot be built. 262 */ 263 private RoutineAliasKey aliasKey; 264 265 public RoutineAliasKey getAliasKey() { 266 return aliasKey; 267 } 268 269 public String getName() { 270 return this.name; 271 } 272 273 public void setName(String name) { 274 this.name = name; 275 } 276 277 public Pair3<Long, Long, String> getStartPosition() { 278 return this.startPosition; 279 } 280 281 public Pair3<Long, Long, String> getEndPosition() { 282 return this.endPosition; 283 } 284 285 public String getFullName() { 286 return this.fullName; 287 } 288 289 public void setFullName(String fullName) { 290 this.fullName = fullName; 291 } 292 293 public List<Argument> getArguments() { 294 return this.arguments; 295 } 296 297 public void setArguments(List<Argument> arguments) { 298 this.arguments = arguments; 299 } 300 301 public void addArgument(Argument argument) { 302 if (argument != null && !this.arguments.contains(argument)) { 303 this.arguments.add(argument); 304 } 305 306 } 307 308 public List<Procedure> getProcedures() { 309 return this.procedures; 310 } 311 312 public void setProcedures(List<Procedure> procedures) { 313 this.procedures = procedures; 314 } 315 316 public void addProcedure(Procedure procedure) { 317 if (procedure != null && !this.procedures.contains(procedure)) { 318 this.procedures.add(procedure); 319 } 320 } 321 322 public ESqlStatementType getType() { 323 return this.type; 324 } 325 326 public void setType(ESqlStatementType type) { 327 this.type = type; 328 } 329 330 public TParseTreeNode getProcedureObject() { 331 return this.procedureObject; 332 } 333 334 public void setProcedureObject(TParseTreeNode procedureObject) { 335 this.procedureObject = procedureObject; 336 } 337 338 public void setId(int id) { 339 this.id = id; 340 } 341 342 public void setStartPosition(Pair3<Long, Long, String> startPosition) { 343 this.startPosition = startPosition; 344 } 345 346 public void setEndPosition(Pair3<Long, Long, String> endPosition) { 347 this.endPosition = endPosition; 348 } 349 350 public String getDatabase() { 351 return database; 352 } 353 354 public String getSchema() { 355 return schema; 356 } 357 358 public String getServer() { 359 return server; 360 } 361}