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.getAstext()).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                return ModelBindingManager.getEffectiveDefaultDatabase();
220        }
221
222        private TObjectName getPackageName() {
223                if(procedureObject instanceof TTeradataCreateProcedure)
224                {
225                        return ((TTeradataCreateProcedure)procedureObject).getProcedureName();
226                }
227                if(procedureObject instanceof TStoredProcedureSqlStatement)
228                {
229                        return ((TStoredProcedureSqlStatement)procedureObject).getStoredProcedureName();
230                }
231                if(procedureObject instanceof TFunctionCall)
232                {
233                        return ((TFunctionCall)procedureObject).getFunctionName();
234                }
235                return null;
236        }
237
238        public long getId() {
239                return this.id;
240        }
241
242        public String getName() {
243                return this.name;
244        }
245
246        public void setName(String name) {
247                this.name = name;
248        }
249
250        public Pair3<Long, Long, String> getStartPosition() {
251                return this.startPosition;
252        }
253
254        public Pair3<Long, Long, String> getEndPosition() {
255                return this.endPosition;
256        }
257
258        public String getFullName() {
259                return this.fullName;
260        }
261
262        public void setFullName(String fullName) {
263                this.fullName = fullName;
264        }
265
266        public List<Argument> getArguments() {
267                return this.arguments;
268        }
269
270        public void setArguments(List<Argument> arguments) {
271                this.arguments = arguments;
272        }
273
274        public void addArgument(Argument argument) {
275                if (argument != null && !this.arguments.contains(argument)) {
276                        this.arguments.add(argument);
277                }
278
279        }
280        
281        public List<Procedure> getProcedures() {
282                return this.procedures;
283        }
284
285        public void setProcedures(List<Procedure> procedures) {
286                this.procedures = procedures;
287        }
288
289        public void addProcedure(Procedure procedure) {
290                if (procedure != null && !this.procedures.contains(procedure)) {
291                        this.procedures.add(procedure);
292                }
293        }
294
295        public ESqlStatementType getType() {
296                return this.type;
297        }
298
299        public void setType(ESqlStatementType type) {
300                this.type = type;
301        }
302
303        public TParseTreeNode getProcedureObject() {
304                return this.procedureObject;
305        }
306
307        public void setProcedureObject(TParseTreeNode procedureObject) {
308                this.procedureObject = procedureObject;
309        }
310
311        public void setId(int id) {
312                this.id = id;
313        }
314
315        public void setStartPosition(Pair3<Long, Long, String> startPosition) {
316                this.startPosition = startPosition;
317        }
318
319        public void setEndPosition(Pair3<Long, Long, String> endPosition) {
320                this.endPosition = endPosition;
321        }
322
323        public String getDatabase() {
324                return database;
325        }
326
327        public String getSchema() {
328                return schema;
329        }
330
331        public String getServer() {
332                return server;
333        }
334}