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 OraclePackage {
026        private static final Logger logger = LoggerFactory.getLogger(OraclePackage.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 List<Procedure> procedures = new ArrayList<Procedure>();
037        private ESqlStatementType type;
038        private TParseTreeNode procedureObject;
039
040        public OraclePackage(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 = getPackageName();
047                        TSourceToken startToken = procedureName.getStartToken();
048                        TSourceToken endToken = procedureName.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                        if (!supportCatalog) {
086                                this.database = null;
087                        } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
088                                this.database = getDefaultDatabase();
089                        }
090
091                        if (!supportSchema) {
092                                this.schema = null;
093                        } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
094                                this.schema = getDefaultSchema();
095                        }
096                        
097                        updatePackageName(supportCatalog, supportSchema);
098                        
099                        this.type = procedure.sqlstatementtype;
100
101                        if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
102                                this.server = getDefaultServer();
103                        }
104                }
105        }
106
107        protected void updatePackageName(boolean supportCatalog, boolean supportSchema) {
108                List<String> segments = SQLUtil.parseNames(this.name);
109                this.name = segments.get(segments.size() - 1);
110                if (supportCatalog && supportSchema) {
111                        StringBuilder builder = new StringBuilder();
112                        if (segments.size() > 2) {
113                                builder.append(segments.get(segments.size() - 3)).append(".");
114                        } else {
115                                if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) {
116                                        builder.append(this.database).append(".");
117                                }
118                        }
119                        if (segments.size() > 1) {
120                                builder.append(segments.get(segments.size() - 2)).append(".");
121                        } else {
122                                if (builder.length() > 0) {
123                                        if (this.schema == null) {
124                                                if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
125                                                        this.schema = "dbo";
126                                                } else {
127                                                        this.schema = getDefaultSchema();
128                                                }
129                                        }
130                                        else if (TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)
131                                                        && ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
132                                                this.schema = "dbo";
133                                        }
134                                        builder.append(this.schema).append(".");
135                                } else {
136                                        if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) {
137                                                builder.append(this.schema).append(".");
138                                        }
139                                }
140                        }
141                        builder.append(this.name);
142                        this.name = builder.toString();
143                } else if (supportCatalog) {
144                        if (segments.size() > 1) {
145                                this.name = segments.get(segments.size() - 2) + "." + this.name;
146                        }
147                        else {
148                                if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) {
149                                        this.name = this.database + "." + this.name;
150                                }
151                        }
152                } else if (supportSchema) {
153                        if (segments.size() > 1) {
154                                this.name = segments.get(segments.size() - 2) + "." + this.name;
155                        } else {
156                                if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) {
157                                        this.name = this.schema + "." + this.name;
158                                }
159                        }
160                }
161        }
162        
163        private void fillSchemaInfo() {
164                TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek());
165                String sqlComment = null;
166                try {
167                        sqlComment = stmt.getCommentBeforeNode();
168                } catch (Exception e) {
169                }
170                if (!SQLUtil.isEmpty(sqlComment) && (sqlComment.indexOf("db") != -1 || sqlComment.indexOf("schema") != -1)) {
171                        Properties properties = new Properties();
172                        try {
173                                properties.load(
174                                                new ByteArrayInputStream(sqlComment.replace("--", "").trim().replace(",", "\n").getBytes()));
175                                if (SQLUtil.isEmpty(this.server) && properties.containsKey("db-instance")) {
176                                        this.server = properties.getProperty("db-instance");
177                                }
178                                if (SQLUtil.isEmpty(this.database) && properties.containsKey("db")) {
179                                        this.database = properties.getProperty("db");
180                                        if(this.database.indexOf(".")!=-1) {
181                                                String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
182                                                this.database = delimitedChar + SQLUtil.trimColumnStringQuote(this.database) + delimitedChar;
183                                        }
184                                }
185                                if (SQLUtil.isEmpty(this.schema) && properties.containsKey("schema")) {
186                                        this.schema = properties.getProperty("schema");
187                                        if(this.schema.indexOf(".")!=-1) {
188                                                String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
189                                                this.schema = delimitedChar + SQLUtil.trimColumnStringQuote(this.schema) + delimitedChar;
190                                        }
191                                }
192                        } catch (IOException e) {
193                                logger.error("load sql comment properties failed.", e);
194                        }
195                }
196        }
197
198        protected String getDefaultServer() {
199                String defaultServer = null;
200                if (ModelBindingManager.getGlobalSQLEnv() != null) {
201                        defaultServer = ModelBindingManager.getGlobalSQLEnv().getDefaultServerName();
202                }
203                if (!SQLUtil.isEmpty(defaultServer))
204                        return defaultServer;
205                return TSQLEnv.DEFAULT_SERVER_NAME;
206        }
207
208        protected String getDefaultSchema() {
209                String defaultSchema = null;
210                if (ModelBindingManager.getGlobalSQLEnv() != null) {
211                        defaultSchema = ModelBindingManager.getGlobalSQLEnv().getDefaultSchemaName();
212                }
213                if (!SQLUtil.isEmpty(defaultSchema))
214                        return defaultSchema;
215                return TSQLEnv.DEFAULT_SCHEMA_NAME;
216        }
217
218        protected String getDefaultDatabase() {
219                String defaultDatabase = null;
220                if (ModelBindingManager.getGlobalSQLEnv() != null) {
221                        defaultDatabase = ModelBindingManager.getGlobalSQLEnv().getDefaultCatalogName();
222                }
223                if (!SQLUtil.isEmpty(defaultDatabase))
224                        return defaultDatabase;
225                return TSQLEnv.DEFAULT_DB_NAME;
226        }
227
228        private TObjectName getPackageName() {
229                if(procedureObject instanceof TTeradataCreateProcedure)
230                {
231                        return ((TTeradataCreateProcedure)procedureObject).getProcedureName();
232                }
233                if(procedureObject instanceof TStoredProcedureSqlStatement)
234                {
235                        return ((TStoredProcedureSqlStatement)procedureObject).getStoredProcedureName();
236                }
237                if(procedureObject instanceof TFunctionCall)
238                {
239                        return ((TFunctionCall)procedureObject).getFunctionName();
240                }
241                return null;
242        }
243
244        public long getId() {
245                return this.id;
246        }
247
248        public String getName() {
249                return this.name;
250        }
251
252        public void setName(String name) {
253                this.name = name;
254        }
255
256        public Pair3<Long, Long, String> getStartPosition() {
257                return this.startPosition;
258        }
259
260        public Pair3<Long, Long, String> getEndPosition() {
261                return this.endPosition;
262        }
263
264        public String getFullName() {
265                return this.fullName;
266        }
267
268        public void setFullName(String fullName) {
269                this.fullName = fullName;
270        }
271
272        public List<Argument> getArguments() {
273                return this.arguments;
274        }
275
276        public void setArguments(List<Argument> arguments) {
277                this.arguments = arguments;
278        }
279
280        public void addArgument(Argument argument) {
281                if (argument != null && !this.arguments.contains(argument)) {
282                        this.arguments.add(argument);
283                }
284
285        }
286        
287        public List<Procedure> getProcedures() {
288                return this.procedures;
289        }
290
291        public void setProcedures(List<Procedure> procedures) {
292                this.procedures = procedures;
293        }
294
295        public void addProcedure(Procedure procedure) {
296                if (procedure != null && !this.procedures.contains(procedure)) {
297                        this.procedures.add(procedure);
298                }
299        }
300
301        public ESqlStatementType getType() {
302                return this.type;
303        }
304
305        public void setType(ESqlStatementType type) {
306                this.type = type;
307        }
308
309        public TParseTreeNode getProcedureObject() {
310                return this.procedureObject;
311        }
312
313        public void setProcedureObject(TParseTreeNode procedureObject) {
314                this.procedureObject = procedureObject;
315        }
316
317        public void setId(int id) {
318                this.id = id;
319        }
320
321        public void setStartPosition(Pair3<Long, Long, String> startPosition) {
322                this.startPosition = startPosition;
323        }
324
325        public void setEndPosition(Pair3<Long, Long, String> endPosition) {
326                this.endPosition = endPosition;
327        }
328
329        public String getDatabase() {
330                return database;
331        }
332
333        public String getSchema() {
334                return schema;
335        }
336
337        public String getServer() {
338                return server;
339        }
340}