001package gudusoft.gsqlparser.dlineage.dataflow.metadata.grabit;
002
003import java.util.Collections;
004import java.util.Comparator;
005import java.util.LinkedHashMap;
006import java.util.List;
007import java.util.Map;
008
009import gudusoft.gsqlparser.EDbVendor;
010import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataAnalyzer;
011import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager;
012import gudusoft.gsqlparser.dlineage.dataflow.model.xml.column;
013import gudusoft.gsqlparser.dlineage.dataflow.model.xml.dataflow;
014import gudusoft.gsqlparser.dlineage.dataflow.model.xml.procedure;
015import gudusoft.gsqlparser.dlineage.dataflow.model.xml.table;
016import gudusoft.gsqlparser.dlineage.util.Pair3;
017import gudusoft.gsqlparser.sqlenv.TSQLEnv;
018import gudusoft.gsqlparser.util.SQLUtil;
019import gudusoft.gsqlparser.util.json.JSON;
020
021public class GrabitMetadataAnalyzer implements MetadataAnalyzer<String> {
022
023        private Map<String, procedure> procedureMap = new LinkedHashMap<String, procedure>();
024        private Map<String, table> tableMap = new LinkedHashMap<String, table>();
025        private Map<String, column> columnMap = new LinkedHashMap<String, column>();
026        private EDbVendor vendor;
027
028        @Override
029        public synchronized dataflow analyzeMetadata(EDbVendor vendor, String metadata) {
030                init(vendor);
031                dataflow dataflow = new dataflow();
032                Map json = (Map) JSON.parseObject(metadata.trim());
033        if (json.containsKey("createdBy")) {
034            String createdBy = (String) json.get("createdBy");
035            if (createdBy.toLowerCase().indexOf("grabit") != -1) {
036                List databases = (List) json.get("databases");
037                        if (databases != null) {
038                        
039                                for (int i = 0; i < databases.size(); i++) {
040                                        Map jsonDatabase = (Map) databases.get(i);
041                                        String databaseName = (String) jsonDatabase.get("name");
042                                        List tables = (List) jsonDatabase.get("tables");
043                                        for (int j = 0; j < tables.size(); j++) {
044                                                Map jsonTable = (Map) tables.get(j);
045                                                        databaseName = (String) jsonTable.get("database");
046                                                        if(databaseName.indexOf(".")!=-1) {
047                                                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
048                                                                databaseName = delimitedChar + SQLUtil.trimColumnStringQuote(databaseName) + delimitedChar;
049                                                        }
050                                                String schemeName = (String) jsonTable.get("schema");
051                                                if(schemeName.indexOf(".")!=-1) {
052                                                        String delimitedChar = TSQLEnv.delimitedChar(vendor);
053                                                        schemeName = delimitedChar + SQLUtil.trimColumnStringQuote(schemeName) + delimitedChar;
054                                                }
055                                                String tableName = (String) jsonTable.get("name");
056                                                if(tableName.indexOf(".")!=-1) {
057                                                        String delimitedChar = TSQLEnv.delimitedChar(vendor);
058                                                        tableName = delimitedChar + SQLUtil.trimColumnStringQuote(tableName) + delimitedChar;
059                                                }
060                                                boolean isView = false;
061                                                if (jsonTable.containsKey("isView")) {
062                                                        isView = Boolean.parseBoolean((String) jsonTable.get("isView"));
063                                                }
064                                                List columns = (List) jsonTable.get("columns");
065                                                for (int k = 0; k < columns.size(); k++) {
066                                                        Map jsonColumn = (Map) columns.get(k);
067                                                        String columnName = (String) jsonColumn.get("name");
068                                                        appendTable(dataflow, databaseName, schemeName, tableName, isView, columnName);
069                                                }
070                                        }
071                                }
072                        }
073            }
074        }
075                sortTableColumns(dataflow);
076                return dataflow;
077        }
078
079        private void init(EDbVendor vendor) {
080                this.vendor = vendor;
081                procedureMap.clear();
082                tableMap.clear();
083                columnMap.clear();
084                if (ModelBindingManager.get() == null) {
085                        ModelBindingManager.set(new ModelBindingManager());
086                }
087        }
088
089        private void sortTableColumns(dataflow dataflow) {
090                if (dataflow.getTables() != null) {
091                        for (table table : dataflow.getTables()) {
092                                Collections.sort(table.getColumns(), new Comparator<column>() {
093                                        public int compare(column t1, column t2) {
094                                                if (t1.getName().equalsIgnoreCase("RelationRows"))
095                                                        return 1;
096                                                if (t2.getName().equalsIgnoreCase("RelationRows"))
097                                                        return -1;
098                                                return 0;
099                                        }
100                                });
101                        }
102                }
103
104                if (dataflow.getResultsets() != null) {
105                        for (table table : dataflow.getResultsets()) {
106                                Collections.sort(table.getColumns(), new Comparator<column>() {
107                                        public int compare(column t1, column t2) {
108                                                if (t1.getName().equalsIgnoreCase("RelationRows"))
109                                                        return 1;
110                                                if (t2.getName().equalsIgnoreCase("RelationRows"))
111                                                        return -1;
112                                                return 0;
113                                        }
114                                });
115                        }
116                }
117        }
118
119        private void appendTable(dataflow dataflow, String databaseName, String schemaName, String tableName,
120                        boolean isView, String columnName) {
121                String tableKey = getFullName(databaseName, schemaName, tableName);
122                if (!tableMap.containsKey(tableKey)) {
123                        table table = new table();
124                        table.setDatabase(databaseName);
125                        table.setSchema(schemaName);
126                        table.setName(tableName);
127                        if (!SQLUtil.isEmpty(table.getSchema()) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(table.getSchema())) {
128                                table.setName(table.getSchema() + "." + table.getName());
129                        }
130                        if (!SQLUtil.isEmpty(table.getDatabase()) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(table.getDatabase())) {
131                                table.setName(table.getDatabase() + "." + table.getName());
132                        }
133                        table.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
134                        table.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
135                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
136                                        + new Pair3<Long, Long, Integer>(-1L, -1L,
137                                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
138                        if (isView) {
139                                table.setType("view");
140                                dataflow.getViews().add(table);
141                        } else {
142                                table.setType("table");
143                                dataflow.getTables().add(table);
144                        }
145                        tableMap.put(tableKey, table);
146                }
147
148                table table = tableMap.get(tableKey);
149                String sourceColumnKey = getFullName(databaseName, schemaName, tableName, columnName);
150                if (!columnMap.containsKey(sourceColumnKey)) {
151                        column column = new column();
152                        column.setId(String.valueOf(++ModelBindingManager.get().TABLE_COLUMN_ID));
153                        column.setName(columnName);
154                        if ("RelationRows".equalsIgnoreCase(columnName)) {
155                                column.setSource("system");
156                        }
157                        column.setCoordinate(new Pair3<Long, Long, Integer>(-1L, -1L,
158                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())) + ","
159                                        + new Pair3<Long, Long, Integer>(-1L, -1L,
160                                                        ModelBindingManager.getGlobalSqlInfo().getIndexOf(ModelBindingManager.getGlobalHash())));
161                        table.getColumns().add(column);
162                        columnMap.put(sourceColumnKey, column);
163                }
164        }
165
166        private String getFullName(String... segments) {
167                StringBuilder builder = new StringBuilder();
168                for (int i = 0; i < segments.length; i++) {
169                        builder.append(segments[i]);
170                        if (i < segments.length - 1) {
171                                builder.append(".");
172                        }
173                }
174                return builder.toString().replace("null.", "");
175        }
176}