001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import gudusoft.gsqlparser.EDbVendor;
005import gudusoft.gsqlparser.TCustomSqlStatement;
006import gudusoft.gsqlparser.TSourceToken;
007import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
008import gudusoft.gsqlparser.dlineage.util.Pair3;
009import gudusoft.gsqlparser.nodes.TParseTreeNode;
010import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
011import gudusoft.gsqlparser.sqlenv.TSQLEnv;
012import gudusoft.gsqlparser.util.Logger;
013import gudusoft.gsqlparser.util.LoggerFactory;
014import gudusoft.gsqlparser.util.SQLUtil;
015
016import java.io.ByteArrayInputStream;
017import java.io.IOException;
018import java.util.*;
019import java.util.concurrent.atomic.AtomicInteger;
020
021public class ResultSet {
022    private static final Logger logger = LoggerFactory.getLogger(ResultSet.class);
023    private long id;
024    protected String server;
025    protected String schema;
026    protected String database;
027    private Pair3<Long, Long, String> startPosition;
028    private Pair3<Long, Long, String> endPosition;
029    private List<ResultColumn> columns = new ArrayList<ResultColumn>();
030
031    private TParseTreeNode gspObject;
032    private boolean isTarget;
033    private boolean isDetermined;
034
035    private ResultSetRelationRows relationRows = new ResultSetRelationRows(this);
036
037    private Map<String, AtomicInteger> aliasMap = new HashMap<>();
038    
039    private String procedureId;
040    
041    public ResultSet(TParseTreeNode gspObject, boolean isTarget) {
042        if (gspObject == null) {
043            throw new IllegalArgumentException("ResultSet arguments can't be null.");
044        }
045
046        id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
047
048        this.gspObject = gspObject;
049        this.isTarget = isTarget;
050
051        TSourceToken startToken = gspObject.getStartToken();
052        TSourceToken endToken = gspObject.getEndToken();
053        if (startToken != null) {
054            this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo,
055                    startToken.columnNo, ModelBindingManager.getGlobalHash());
056        }
057        
058        if (endToken != null) {
059            this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
060                    endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash());
061        }
062        
063        this.schema = ModelBindingManager.getGlobalSchema();
064        this.database = ModelBindingManager.getGlobalDatabase();
065
066        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
067        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
068        boolean supportSchema = TSQLEnv.supportSchema(vendor);
069        
070        fillSchemaInfo();
071        
072        if (!supportCatalog) {
073            this.database = null;
074        } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
075            this.database = getDefaultDatabase();
076        }
077
078        if (!supportSchema) {
079            this.schema = null;
080        } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
081            this.schema = getDefaultSchema();
082        }
083
084        if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
085            this.server = getDefaultServer();
086        }
087    }
088
089    private void fillSchemaInfo() {
090                TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek());
091                String sqlComment = null;
092                try {
093                        sqlComment = stmt.getCommentBeforeNode();
094                } catch (Exception e) {
095                }
096                if (!SQLUtil.isEmpty(sqlComment) && (sqlComment.indexOf("db") != -1 || sqlComment.indexOf("schema") != -1)) {
097                        Properties properties = new Properties();
098                        try {
099                                properties.load(
100                                                new ByteArrayInputStream(sqlComment.replace("--", "").trim().replace(",", "\n").getBytes()));
101                                if (SQLUtil.isEmpty(this.server) && properties.containsKey("db-instance")) {
102                                        this.server = properties.getProperty("db-instance");
103                                }
104                                if (SQLUtil.isEmpty(this.database) && properties.containsKey("db")) {
105                                        this.database = properties.getProperty("db");
106                                        if(this.database.indexOf(".")!=-1) {
107                                                this.database = SQLUtil.quoteDottedName(ModelBindingManager.getGlobalOption().getVendor(), ESQLDataObjectType.dotCatalog, this.database);
108                                        }
109                                }
110                                if (SQLUtil.isEmpty(this.schema) && properties.containsKey("schema")) {
111                                        this.schema = properties.getProperty("schema");
112                                        if(this.schema.indexOf(".")!=-1) {
113                                                this.schema = SQLUtil.quoteDottedName(ModelBindingManager.getGlobalOption().getVendor(), ESQLDataObjectType.dotSchema, this.schema);
114                                        }
115                                }
116                        } catch (IOException e) {
117                logger.error("load sql comment properties failed.", e);
118                        }
119                }
120        }
121    
122    protected String getDefaultServer() {
123        String defaultServer = null;
124        if (ModelBindingManager.getGlobalSQLEnv() != null) {
125            defaultServer = ModelBindingManager.getGlobalSQLEnv().getDefaultServerName();
126        }
127        if (!SQLUtil.isEmpty(defaultServer))
128            return defaultServer;
129        return TSQLEnv.DEFAULT_SERVER_NAME;
130    }
131
132    protected String getDefaultSchema() {
133        return ModelBindingManager.getEffectiveDefaultSchema();
134    }
135
136    protected String getDefaultDatabase() {
137        return ModelBindingManager.getEffectiveDefaultDatabase();
138    }
139
140    public Pair3<Long, Long, String> getStartPosition() {
141        return startPosition;
142    }
143
144    public Pair3<Long, Long, String> getEndPosition() {
145        return endPosition;
146    }
147
148    public List<ResultColumn> getColumns() {
149        return columns;
150    }
151
152    public void addColumn(ResultColumn column) {
153        if (column != null && !columns.contains(column)) {
154            this.columns.add(column);
155        }
156    }
157
158    public TParseTreeNode getGspObject() {
159        return gspObject;
160    }
161
162    public long getId() {
163        return id;
164    }
165
166    public boolean isTarget() {
167        return isTarget;
168    }
169
170        public String getSchema() {
171                return schema;
172        }
173
174        public String getDatabase() {
175                return database;
176        }
177        
178        public ResultSetRelationRows getRelationRows(){
179                return relationRows;
180        }
181
182    public String getServer() {
183        return server;
184    }
185
186        public boolean isDetermined() {
187                return isDetermined;
188        }
189
190        public void setDetermined(boolean isDetermined) {
191                this.isDetermined = isDetermined;
192        }
193
194        public void setTarget(boolean isTarget) {
195                this.isTarget = isTarget;
196        }
197
198    Map<String, AtomicInteger> getAliasMap() {
199        return aliasMap;
200    }
201
202    public String getProcedureId() {
203        return procedureId;
204    }
205
206    public void setProcedureId(String procedureId) {
207        this.procedureId = procedureId;
208    }
209}