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