001package gudusoft.gsqlparser.dlineage.util;
002
003import java.io.File;
004import java.util.ArrayList;
005import java.util.HashMap;
006import java.util.LinkedHashMap;
007import java.util.LinkedHashSet;
008import java.util.List;
009import java.util.Map;
010
011import gudusoft.gsqlparser.EDbVendor;
012import gudusoft.gsqlparser.dlineage.DataFlowAnalyzer;
013import gudusoft.gsqlparser.dlineage.dataflow.model.xml.column;
014import gudusoft.gsqlparser.dlineage.dataflow.model.xml.dataflow;
015import gudusoft.gsqlparser.dlineage.dataflow.model.xml.relationship;
016import gudusoft.gsqlparser.dlineage.dataflow.model.xml.sourceColumn;
017import gudusoft.gsqlparser.dlineage.dataflow.model.xml.table;
018import gudusoft.gsqlparser.dlineage.dataflow.model.xml.targetColumn;
019import gudusoft.gsqlparser.util.SQLUtil;
020import gudusoft.gsqlparser.util.json.JSON;
021
022public class TableColumnUtility {
023
024        public static class Table {
025                private String name;
026                private String type;
027                private String coordinate;
028                private List<Column> columns;
029
030                public String getName() {
031                        return name;
032                }
033
034                public void setName(String name) {
035                        this.name = name;
036                }
037
038                public String getType() {
039                        return type;
040                }
041
042                public void setType(String type) {
043                        this.type = type;
044                }
045
046                public List<Column> getColumns() {
047                        return columns;
048                }
049
050                public void setColumns(List<Column> columns) {
051                        this.columns = columns;
052                }
053
054                public String getCoordinate() {
055                        return coordinate;
056                }
057
058                public void setCoordinate(String coordinate) {
059                        this.coordinate = coordinate;
060                }
061        }
062
063        public static class Column implements Cloneable {
064                private String id;
065                private String table;
066                private String name;
067                private String dataType;
068                private String effectType;
069                private String joinColumn;
070                private String coordinates;
071
072                public String getName() {
073                        return name;
074                }
075
076                public void setName(String name) {
077                        this.name = name;
078                }
079
080                public String getDataType() {
081                        return dataType;
082                }
083
084                public void setDataType(String dataType) {
085                        this.dataType = dataType;
086                }
087
088                public String getId() {
089                        return id;
090                }
091
092                public void setId(String id) {
093                        this.id = id;
094                }
095
096                public String getEffectType() {
097                        return effectType;
098                }
099
100                public void setEffectType(String effectType) {
101                        this.effectType = effectType;
102                }
103
104                public String getJoinColumn() {
105                        return joinColumn;
106                }
107
108                public void setJoinColumn(String joinColumn) {
109                        this.joinColumn = joinColumn;
110                }
111
112                public String getCoordinates() {
113                        return coordinates;
114                }
115
116                public void setCoordinates(String coordinates) {
117                        this.coordinates = coordinates;
118                }
119
120                public String getTable() {
121                        return table;
122                }
123
124                public void setTable(String table) {
125                        this.table = table;
126                }
127
128                
129
130                @Override
131                public int hashCode() {
132                        final int prime = 31;
133                        int result = 1;
134                        result = prime * result + ((effectType == null) ? 0 : effectType.hashCode());
135                        result = prime * result + ((id == null) ? 0 : id.hashCode());
136                        result = prime * result + ((joinColumn == null) ? 0 : joinColumn.hashCode());
137                        return result;
138                }
139
140                @Override
141                public boolean equals(Object obj) {
142                        if (this == obj)
143                                return true;
144                        if (obj == null)
145                                return false;
146                        if (getClass() != obj.getClass())
147                                return false;
148                        Column other = (Column) obj;
149                        if (effectType == null) {
150                                if (other.effectType != null)
151                                        return false;
152                        } else if (!effectType.equals(other.effectType))
153                                return false;
154                        if (id == null) {
155                                if (other.id != null)
156                                        return false;
157                        } else if (!id.equals(other.id))
158                                return false;
159                        if (joinColumn == null) {
160                                if (other.joinColumn != null)
161                                        return false;
162                        } else if (!joinColumn.equals(other.joinColumn))
163                                return false;
164                        return true;
165                }
166
167                @Override
168                public Column clone() throws CloneNotSupportedException {
169                        return (Column) super.clone();
170                }
171        }
172
173        public String getTableColumnDetail(dataflow dataflow) throws Exception {
174                List<Table> tables = new ArrayList<Table>();
175                List<Column> columns = new ArrayList<Column>();
176                for (table table : dataflow.getTables()) {
177                        if (!(table.isTable() || table.isView())) {
178                                continue;
179                        }
180                        if ("constantTable".equals(table.getType())) {
181                                continue;
182                        }
183                        if ("function".equals(table.getSubType())) {
184                                continue;
185                        }
186                        Map<String, Column> columnMap = new HashMap<String, Column>();
187                        Table tableItem = new Table();
188                        tableItem.setName(table.getName());
189                        tableItem.setType(table.getType());
190                        tableItem.setCoordinate(table.getCoordinate());
191                        tables.add(tableItem);
192                        if (table.getColumns() != null) {
193                                for (column column : table.getColumns()) {
194                                        if ("system".equals(column.getSource())) {
195                                                continue;
196                                        } else {
197                                                Column columnItem = new Column();
198                                                columnItem.setId(column.getId());
199                                                columnItem.setName(column.getName());
200                                                columnItem.setTable(tableItem.getName());
201                                                columnItem.setDataType(column.getDataType());
202                                                columnMap.put(columnItem.getId(), columnItem);
203                                        }
204                                }
205                        }
206
207                        Map<Column, LinkedHashSet<String>> columnCoordinates = new HashMap<Column, LinkedHashSet<String>>();
208                        if (dataflow.getRelationships() != null) {
209                                for (relationship relation : dataflow.getRelationships()) {
210                                        if (!("fdd".equals(relation.getType()) || "join".equals(relation.getType()))) {
211                                                continue;
212                                        }
213
214                                        targetColumn targetColumn = relation.getTarget();
215                                        if (targetColumn != null && columnMap.containsKey(targetColumn.getId())) {
216                                                if (!columnMap.containsKey(targetColumn.getId())) {
217                                                        continue;
218                                                }
219                                                Column column = columnMap.get(targetColumn.getId()).clone();
220                                                if ("join".equals(relation.getType())) {
221                                                        column.setEffectType("join");
222                                                        if (relation.getSources() != null && relation.getSources().size() > 0) {
223                                                                sourceColumn sourceColumn = relation.getSources().get(0);
224                                                                String columnName = sourceColumn.getColumn();
225                                                                if (!SQLUtil.isEmpty(sourceColumn.getParent_name())) {
226                                                                        columnName = sourceColumn.getParent_name() + "." + columnName;
227                                                                }
228                                                                column.setJoinColumn(columnName);
229                                                        }
230                                                } else {
231                                                        column.setEffectType(relation.getEffectType());
232                                                }
233                                                if (!columnCoordinates.containsKey(column)) {
234                                                        columnCoordinates.put(column, new LinkedHashSet<String>());
235                                                }
236                                                columnCoordinates.get(column).add(targetColumn.getCoordinate());
237                                        }
238
239                                        if (relation.getSources() != null) {
240                                                for (sourceColumn sourceColumn : relation.getSources()) {
241                                                        if (!columnMap.containsKey(sourceColumn.getId())) {
242                                                                continue;
243                                                        }
244                                                        Column column = columnMap.get(sourceColumn.getId()).clone();
245                                                        if ("join".equals(relation.getType())) {
246                                                                column.setEffectType("join");
247                                                                if (relation.getTarget() != null) {
248                                                                        String columnName = targetColumn.getColumn();
249                                                                        if (!SQLUtil.isEmpty(targetColumn.getParent_name())) {
250                                                                                columnName = targetColumn.getParent_name() + "." + columnName;
251                                                                        }
252                                                                        column.setJoinColumn(columnName);
253                                                                }
254                                                        } else {
255                                                                column.setEffectType(relation.getEffectType());
256                                                        }
257                                                        if (!columnCoordinates.containsKey(column)) {
258                                                                columnCoordinates.put(column, new LinkedHashSet<String>());
259                                                        }
260                                                        columnCoordinates.get(column).add(sourceColumn.getCoordinate());
261                                                }
262                                        }
263                                }
264                        }
265                        for (Column column : columnCoordinates.keySet()) {
266                                column.setCoordinates(String.join(",", columnCoordinates.get(column).toArray(new String[0])));
267                                columns.add(column);
268                        }
269
270                        columns.sort((t1, t2) -> {
271                                return (t1.getTable() + "." + t1.getName() + ":" + t1.getEffectType())
272                                                .compareTo((t2.getTable() + "." + t2.getName() + ":" + t2.getEffectType()));
273                        });
274                        columns.forEach(t -> t.setId(null));
275                }
276
277                tables.sort((t1, t2) -> {
278                        return t1.name.compareTo(t2.name);
279                });
280                Map map = new LinkedHashMap<>();
281                map.put("tables", tables);
282                map.put("columns", columns);
283                return JSON.toJSONString(map);
284        }
285
286        public String getTableColumnSummary(dataflow dataflow) {
287                List<Table> tables = new ArrayList<Table>();
288                for (table table : dataflow.getTables()) {
289                        if (!(table.isTable() || table.isView())) {
290                                continue;
291                        }
292                        if ("constantTable".equals(table.getType())) {
293                                continue;
294                        }
295                        if ("function".equals(table.getSubType())) {
296                                continue;
297                        }
298                        Table tableItem = new Table();
299                        tableItem.setName(table.getName());
300                        tableItem.setType(table.getType());
301                        tables.add(tableItem);
302                        if (table.getColumns() != null) {
303                                List<Column> columns = new ArrayList<Column>();
304                                for (column column : table.getColumns()) {
305                                        if ("system".equals(column.getSource())) {
306                                                continue;
307                                        } else {
308                                                Column columnItem = new Column();
309                                                columnItem.setTable(tableItem.getName());
310                                                columnItem.setName(column.getName());
311                                                columnItem.setDataType(column.getDataType());
312                                                columns.add(columnItem);
313                                        }
314                                }
315                                columns.sort((t1, t2) -> {
316                                        return (t1.getTable() + "." + t1.getName() + ":" + t1.getEffectType())
317                                                        .compareTo((t2.getTable() + "." + t2.getName() + ":" + t2.getEffectType()));
318                                });
319                                tableItem.setColumns(columns);
320                        }
321                }
322                tables.sort((t1, t2) -> {
323                        return t1.name.compareTo(t2.name);
324                });
325                Map map = new LinkedHashMap<>();
326                map.put("tables", tables);
327                return JSON.toJSONString(map);
328        }
329
330        public static void main(String[] args) throws Exception {
331                DataFlowAnalyzer analyzer = new DataFlowAnalyzer(new File("D:\\1.txt"), EDbVendor.dbvoracle, false);
332                analyzer.getOption().setShowJoin(true);
333                analyzer.generateDataFlow();
334                dataflow dataflow = analyzer.getDataFlow();
335                System.out.println(new TableColumnUtility().getTableColumnDetail(dataflow));
336
337        }
338
339}