001package gudusoft.gsqlparser.dlineage.util; 002 003import java.util.List; 004import java.util.Map; 005 006import gudusoft.gsqlparser.EDbVendor; 007import gudusoft.gsqlparser.TCustomSqlStatement; 008import gudusoft.gsqlparser.TGSqlParser; 009import gudusoft.gsqlparser.TSourceToken; 010import gudusoft.gsqlparser.TStatementList; 011import gudusoft.gsqlparser.dlineage.DataFlowAnalyzer; 012import gudusoft.gsqlparser.dlineage.ParallelDataFlowAnalyzer; 013import gudusoft.gsqlparser.dlineage.dataflow.model.DbObjectPosition; 014import gudusoft.gsqlparser.dlineage.dataflow.model.SqlInfo; 015import gudusoft.gsqlparser.dlineage.dataflow.model.json.Coordinate; 016import gudusoft.gsqlparser.dlineage.dataflow.model.xml.PositionUtil; 017import gudusoft.gsqlparser.util.IndexedLinkedHashMap; 018import gudusoft.gsqlparser.util.SQLUtil; 019import gudusoft.gsqlparser.util.json.JSON; 020 021@SuppressWarnings("unchecked") 022public class SqlInfoHelper { 023 024 private IndexedLinkedHashMap<String, Object> sqlInfo; 025 026 public static String getSqlInfoJson(DataFlowAnalyzer analyzer) { 027 return analyzer.generateSqlInfos(); 028 } 029 030 public static String getSqlInfoJson(ParallelDataFlowAnalyzer analyzer) { 031 return analyzer.generateSqlInfos(); 032 } 033 034 public SqlInfoHelper(String sqlInfoJson) { 035 sqlInfo = (IndexedLinkedHashMap<String, Object>) JSON.parseObject(sqlInfoJson); 036 } 037 038 @SuppressWarnings("rawtypes") 039 public SqlInfoHelper(DataFlowAnalyzer analyzer) { 040 if (sqlInfo == null) { 041 sqlInfo = (IndexedLinkedHashMap) analyzer.getSqlInfos(); 042 } 043 } 044 045 public static Coordinate[][] parseCoordinateString(String coordinate) { 046 if (coordinate.indexOf("{") != -1 && coordinate.indexOf("}") != -1) { 047 List<Map<String, Object>> items = (List<Map<String, Object>>) JSON.parseObject(coordinate); 048 Coordinate[][] coordinates = new Coordinate[items.size() / 2][2]; 049 for (int i = 0; i < coordinates.length; i++) { 050 Map<String, Object> startMap = items.get(2 * i); 051 Map<String, Object> endMap = items.get(2 * i + 1); 052 Coordinate start = new Coordinate(Long.valueOf(startMap.get("x").toString()), 053 Long.valueOf(startMap.get("y").toString()), (String) startMap.get("hashCode")); 054 Coordinate end = new Coordinate(Long.valueOf(endMap.get("x").toString()), 055 Long.valueOf(endMap.get("y").toString()), (String) endMap.get("hashCode")); 056 Coordinate[] pair = new Coordinate[] { start, end }; 057 coordinates[i] = pair; 058 } 059 return coordinates; 060 } else { 061 int count = PositionUtil.getOccurrencesNumber(coordinate); 062 Coordinate[][] coordinates = new Coordinate[count][2]; 063 for (int i = 0; i < count; i++) { 064 Coordinate start = PositionUtil.getStartPos(coordinate, i); 065 Coordinate end = PositionUtil.getEndPos(coordinate, i); 066 067 Coordinate[] pair = new Coordinate[] { start, end }; 068 coordinates[i] = pair; 069 } 070 return coordinates; 071 } 072 } 073 074 @SuppressWarnings("rawtypes") 075 public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) { 076 if(start == null || end == null){ 077 throw new IllegalArgumentException("Coordinate can't be null."); 078 } 079 080 String hashCode = start.getHashCode(); 081 int dbObjectStartLine = (int) start.getX() - 1; 082 int dbObjectStarColumn = (int) start.getY() - 1; 083 int dbObjectEndLine = (int) end.getX() - 1; 084 int dbObjectEndColumn = (int) end.getY() - 1; 085 086 if(hashCode == null){ 087 throw new IllegalArgumentException("Coordinate hashcode can't be null."); 088 } 089 090 List sqlInfoList; 091 if (hashCode.matches("\\d+")) { 092 sqlInfoList = (List) sqlInfo.getValueAtIndex(Integer.valueOf(hashCode)); 093 } else { 094 sqlInfoList = (List) sqlInfo.get(hashCode); 095 } 096 if (sqlInfoList == null) { 097 return null; 098 } 099 for (int j = 0; j < sqlInfoList.size(); j++) { 100 Object item = sqlInfoList.get(j); 101 if (item instanceof Map) { 102 Map<String, Object> sqlInfo = (Map<String, Object>) item; 103 int startLine = Integer.valueOf(sqlInfo.get("lineStart").toString()); 104 int endLine = Integer.valueOf(sqlInfo.get("lineEnd").toString()); 105 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 106 DbObjectPosition position = new DbObjectPosition(); 107 position.setFile((String) sqlInfo.get("fileName")); 108 position.setFilePath((String) sqlInfo.get("filePath")); 109 position.setSql((String) sqlInfo.get("sql")); 110 position.setIndex(Integer.valueOf(sqlInfo.get("originIndex").toString())); 111 List<Pair<Integer, Integer>> positions = position.getPositions(); 112 int originLineStart = Integer.valueOf(sqlInfo.get("originLineStart").toString()); 113 positions.add(new Pair<Integer, Integer>(dbObjectStartLine - startLine + originLineStart + 1, 114 dbObjectStarColumn + 1)); 115 positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + originLineStart + 1, 116 dbObjectEndColumn + 1)); 117 return position; 118 } 119 } else if (item instanceof SqlInfo) { 120 SqlInfo sqlInfo = (SqlInfo) item; 121 int startLine = sqlInfo.getLineStart(); 122 int endLine = sqlInfo.getLineEnd(); 123 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 124 DbObjectPosition position = new DbObjectPosition(); 125 position.setFile(sqlInfo.getFileName()); 126 position.setFilePath(sqlInfo.getFilePath()); 127 position.setSql(sqlInfo.getSql()); 128 position.setIndex(sqlInfo.getOriginIndex()); 129 List<Pair<Integer, Integer>> positions = position.getPositions(); 130 int originLineStart = sqlInfo.getOriginLineStart(); 131 positions.add(new Pair<Integer, Integer>(dbObjectStartLine - startLine + originLineStart + 1, 132 dbObjectStarColumn + 1)); 133 positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + originLineStart + 1, 134 dbObjectEndColumn + 1)); 135 return position; 136 } 137 } 138 } 139 return null; 140 } 141 142 @SuppressWarnings("rawtypes") 143 public DbObjectPosition getSelectedDbObjectStatementInfo(EDbVendor vendor, Coordinate start, Coordinate end) { 144 if(start == null || end == null){ 145 throw new IllegalArgumentException("Coordinate can't be null."); 146 } 147 148 String hashCode = start.getHashCode(); 149 150 if(hashCode == null){ 151 throw new IllegalArgumentException("Coordinate hashcode can't be null."); 152 } 153 154 int dbObjectStartLine = (int) start.getX() - 1; 155 int dbObjectStarColumn = (int) start.getY() - 1; 156 int dbObjectEndLine = (int) end.getX() - 1; 157 int dbObjectEndColumn = (int) end.getY() - 1; 158 List sqlInfoList; 159 if (hashCode.matches("\\d+")) { 160 sqlInfoList = (List) sqlInfo.getValueAtIndex(Integer.valueOf(hashCode)); 161 } else { 162 sqlInfoList = (List) sqlInfo.get(hashCode); 163 } 164 if (sqlInfoList == null) { 165 return null; 166 } 167 for (int j = 0; j < sqlInfoList.size(); j++) { 168 Object item = sqlInfoList.get(j); 169 if (item instanceof Map) { 170 Map<String, Object> sqlInfo = (Map<String, Object>) sqlInfoList.get(j); 171 int startLine = Integer.valueOf(sqlInfo.get("lineStart").toString()); 172 int endLine = Integer.valueOf(sqlInfo.get("lineEnd").toString()); 173 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 174 DbObjectPosition position = new DbObjectPosition(); 175 position.setFile((String) sqlInfo.get("fileName")); 176 position.setFilePath((String) sqlInfo.get("filePath")); 177 position.setSql((String) sqlInfo.get("sql")); 178 position.setIndex(Integer.valueOf(sqlInfo.get("originIndex").toString())); 179 List<Pair<Integer, Integer>> positions = position.getPositions(); 180 int originLineStart = Integer.valueOf(sqlInfo.get("originLineStart").toString()); 181 182 int startX = dbObjectStartLine - startLine + originLineStart + 1; 183 int startY = dbObjectStarColumn + 1; 184 185 int endX = dbObjectEndLine - startLine + originLineStart + 1; 186 int endY = dbObjectEndColumn + 1; 187 188 TGSqlParser parser = new TGSqlParser(vendor); 189 parser.setSqltext(position.getSql()); 190 parser.getrawsqlstatements(); 191 TStatementList stmts = parser.getSqlstatements(); 192 for (int i = 0; i < stmts.size(); i++) { 193 TCustomSqlStatement stmt = stmts.get(i); 194 TSourceToken startToken = stmt.getStartToken(); 195 TSourceToken endToken = stmt.getEndToken(); 196 long startPosX = startToken.lineNo; 197 long startPosY = startToken.columnNo; 198 199 long endPosX = endToken.lineNo; 200 long endPosY = endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(); 201 String[] segments = endToken.astext.split("\n"); 202 if (segments.length > 1) { 203 endPosX = endToken.lineNo + segments.length - 1; 204 endPosY = segments[segments.length - 1].length() + 1; 205 } 206 207 if (startPosX <= startX && endPosX >= endX) { 208 if (startPosX == startX && startPosY > startY) { 209 continue; 210 } 211 if (endPosX == endX && endPosY < endY) { 212 continue; 213 } 214 215 position.setIndex(i); 216 StringBuffer buffer = new StringBuffer(); 217 if (startPosY > 1) { 218 for (int z = 0; z < startPosY - 1; z++) { 219 buffer.append(" "); 220 } 221 } 222 buffer.append(stmt.toString()); 223 position.setSql(buffer.toString()); 224 225 int offset = (int) startPosX - 1; 226 227 positions.add(new Pair<Integer, Integer>( 228 dbObjectStartLine - startLine + originLineStart + 1 - offset, 229 dbObjectStarColumn + 1)); 230 positions.add(new Pair<Integer, Integer>( 231 dbObjectEndLine - startLine + originLineStart + 1 - offset, dbObjectEndColumn + 1)); 232 233 return position; 234 } else { 235 continue; 236 } 237 } 238 } 239 } else if (item instanceof SqlInfo) { 240 SqlInfo sqlInfo = (SqlInfo) item; 241 int startLine = sqlInfo.getLineStart(); 242 int endLine = sqlInfo.getLineEnd(); 243 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 244 DbObjectPosition position = new DbObjectPosition(); 245 position.setFile(sqlInfo.getFileName()); 246 position.setFilePath(sqlInfo.getFilePath()); 247 position.setSql(sqlInfo.getSql()); 248 position.setIndex(sqlInfo.getOriginIndex()); 249 List<Pair<Integer, Integer>> positions = position.getPositions(); 250 int originLineStart = sqlInfo.getOriginLineStart(); 251 252 int startX = dbObjectStartLine - startLine + originLineStart + 1; 253 int startY = dbObjectStarColumn + 1; 254 255 int endX = dbObjectEndLine - startLine + originLineStart + 1; 256 int endY = dbObjectEndColumn + 1; 257 258 TGSqlParser parser = new TGSqlParser(vendor); 259 parser.setSqltext(position.getSql()); 260 parser.getrawsqlstatements(); 261 TStatementList stmts = parser.getSqlstatements(); 262 for (int i = 0; i < stmts.size(); i++) { 263 TCustomSqlStatement stmt = stmts.get(i); 264 TSourceToken startToken = stmt.getStartToken(); 265 TSourceToken endToken = stmt.getEndToken(); 266 long startPosX = startToken.lineNo; 267 long startPosY = startToken.columnNo; 268 269 long endPosX = endToken.lineNo; 270 long endPosY = endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(); 271 String[] segments = endToken.astext.split("\n"); 272 if (segments.length > 1) { 273 endPosX = endToken.lineNo + segments.length - 1; 274 endPosY = segments[segments.length - 1].length() + 1; 275 } 276 277 if (startPosX <= startX && endPosX >= endX) { 278 if (startPosX == startX && startPosY > startY) { 279 continue; 280 } 281 if (endPosX == endX && endPosY < endY) { 282 continue; 283 } 284 285 position.setIndex(i); 286 StringBuffer buffer = new StringBuffer(); 287 if (startPosY > 1) { 288 for (int z = 0; z < startPosY - 1; z++) { 289 buffer.append(" "); 290 } 291 } 292 buffer.append(stmt.toString()); 293 position.setSql(buffer.toString()); 294 295 int offset = (int) startPosX - 1; 296 297 positions.add(new Pair<Integer, Integer>( 298 dbObjectStartLine - startLine + originLineStart + 1 - offset, 299 dbObjectStarColumn + 1)); 300 positions.add(new Pair<Integer, Integer>( 301 dbObjectEndLine - startLine + originLineStart + 1 - offset, dbObjectEndColumn + 1)); 302 303 return position; 304 } else { 305 continue; 306 } 307 } 308 } 309 } 310 } 311 return null; 312 } 313}