001package gudusoft.gsqlparser.lineage.v2.shape; 002 003import java.util.Collections; 004import java.util.List; 005import java.util.Map; 006 007/** 008 * Mirror of {@code gudusoft.gsqlparser.dlineage.dataflow.model.SqllrObservations}, the recorder, as it stood when the 009 * analysis froze: the root of the shape (plan 09, slice 1b). Hand-written, with its record mirrors, because two of its 010 * members take an argument: they are answered from tables the projection precomputed for every possible argument. 011 * 012 * <p>Internal API of the SQL-LR producer.</p> 013 * 014 * @since 4.2.17 015 */ 016public final class SqllrObservations extends ShapeObject { 017 018 private final Object vUnits; 019 private final Object vElements; 020 private final Object vReferences; 021 private final Object vFrozenRelations; 022 private final Object vFrozenResultSets; 023 private final Object vDerived; 024 private final Object vStatements; 025 private final Map<Integer, Object> frozenColumns; 026 private final Map<Integer, Integer> structItems; 027 028 SqllrObservations(Shape shape, int handle, Object[] v, Map<Integer, Object> frozenColumns, 029 Map<Integer, Integer> structItems) { 030 super(shape, handle); 031 this.vUnits = v[0]; 032 this.vElements = v[1]; 033 this.vReferences = v[2]; 034 this.vFrozenRelations = v[3]; 035 this.vFrozenResultSets = v[4]; 036 this.vDerived = v[5]; 037 this.vStatements = v[6]; 038 this.frozenColumns = Collections.unmodifiableMap(frozenColumns); 039 this.structItems = Collections.unmodifiableMap(structItems); 040 } 041 042 public List<UnitRecord> getUnits() { 043 return slot(vUnits); 044 } 045 046 public List<ElementRecord> getElements() { 047 return slot(vElements); 048 } 049 050 public List<ReferenceRecord> getReferences() { 051 return slot(vReferences); 052 } 053 054 public List<FrozenRelation> getFrozenRelations() { 055 return slot(vFrozenRelations); 056 } 057 058 public List<ResultSet> getFrozenResultSets() { 059 return slot(vFrozenResultSets); 060 } 061 062 public List<DerivedRecord> getDerived() { 063 return slot(vDerived); 064 } 065 066 public List<StatementRecord> getStatements() { 067 return slot(vStatements); 068 } 069 070 /** The columns of a result set at the freeze, or {@code null} when no frozen relationship reaches it. */ 071 public List<ResultColumn> getFrozenColumns(ResultSet resultSet) { 072 Object columns = resultSet == null ? null : frozenColumns.get(Integer.valueOf(resultSet.shapeHandle())); 073 return columns == null ? null : this.<List<ResultColumn>>slot(columns); 074 } 075 076 /** The select item whose STRUCT a field column belongs to, or null. */ 077 public TResultColumn getStructItem(Object column) { 078 if (!(column instanceof ShapeObject)) { 079 return null; 080 } 081 Integer item = structItems.get(Integer.valueOf(((ShapeObject) column).shapeHandle())); 082 return item == null ? null : (TResultColumn) shape.at(item.intValue()); 083 } 084 085 /** Mirror of the recorder's element record. */ 086 public static final class ElementRecord extends ShapeObject { 087 private final Object vRelation; 088 private final Object vElement; 089 private final boolean target; 090 private final Object vReference; 091 private final Object vStatement; 092 private final long sequence; 093 094 ElementRecord(Shape shape, int handle, Object[] v) { 095 super(shape, handle); 096 this.vRelation = v[0]; 097 this.vElement = v[1]; 098 this.target = ((Boolean) v[2]).booleanValue(); 099 this.vReference = v[3]; 100 this.vStatement = v[4]; 101 this.sequence = ((Long) v[5]).longValue(); 102 } 103 104 public AbstractRelationship getRelation() { 105 return slot(vRelation); 106 } 107 108 public RelationshipElement getElement() { 109 return slot(vElement); 110 } 111 112 public boolean isTarget() { 113 return target; 114 } 115 116 public TObjectName getReference() { 117 return slot(vReference); 118 } 119 120 public TCustomSqlStatement getStatement() { 121 return slot(vStatement); 122 } 123 124 public long getSequence() { 125 return sequence; 126 } 127 } 128 129 /** Mirror of the recorder's reference record. */ 130 public static final class ReferenceRecord extends ShapeObject { 131 private final Object vReference; 132 private final Object vTarget; 133 private final Object vStatement; 134 private final long sequence; 135 136 ReferenceRecord(Shape shape, int handle, Object[] v) { 137 super(shape, handle); 138 this.vReference = v[0]; 139 this.vTarget = v[1]; 140 this.vStatement = v[2]; 141 this.sequence = ((Long) v[3]).longValue(); 142 } 143 144 public TObjectName getReference() { 145 return slot(vReference); 146 } 147 148 public Object getTarget() { 149 return slot(vTarget); 150 } 151 152 public TCustomSqlStatement getStatement() { 153 return slot(vStatement); 154 } 155 156 public long getSequence() { 157 return sequence; 158 } 159 } 160 161 /** Mirror of the recorder's statement record. */ 162 public static final class StatementRecord extends ShapeObject { 163 private final Object vStatement; 164 private final String failureClass; 165 private final String failureMessage; 166 private final boolean finished; 167 private final String failureSimpleName; 168 169 StatementRecord(Shape shape, int handle, Object[] v) { 170 super(shape, handle); 171 this.vStatement = v[0]; 172 this.failureClass = (String) v[1]; 173 this.failureMessage = (String) v[2]; 174 this.finished = ((Boolean) v[3]).booleanValue(); 175 this.failureSimpleName = (String) v[4]; 176 } 177 178 /** The simple name of the class of the exception that ended the statement's analysis, or {@code null}. */ 179 public String getFailureSimpleName() { 180 return failureSimpleName; 181 } 182 183 public TCustomSqlStatement getStatement() { 184 return slot(vStatement); 185 } 186 187 /** 188 * The exception that ended the statement's analysis, made again from its class and message (the snapshot 189 * holds no Throwable), or {@code null}. 190 */ 191 public Throwable getFailure() { 192 if (failureClass == null) { 193 return null; 194 } 195 try { 196 Class<?> c = Class.forName(failureClass); 197 try { 198 return (Throwable) c.getConstructor(String.class).newInstance(failureMessage); 199 } catch (NoSuchMethodException e) { 200 return (Throwable) c.getConstructor().newInstance(); 201 } 202 } catch (Exception e) { 203 return new IllegalStateException(failureClass + ": " + failureMessage); 204 } 205 } 206 207 public boolean isFinished() { 208 return finished; 209 } 210 } 211 212 /** Mirror of the recorder's unit record. */ 213 public static final class UnitRecord extends ShapeObject { 214 private final int unitIndex; 215 private final int parseResult; 216 private final Object vStatements; 217 private final Object vSyntaxErrors; 218 private final Object vRecoveredSyntaxErrors; 219 220 UnitRecord(Shape shape, int handle, Object[] v) { 221 super(shape, handle); 222 this.unitIndex = ((Integer) v[0]).intValue(); 223 this.parseResult = ((Integer) v[1]).intValue(); 224 this.vStatements = v[2]; 225 this.vSyntaxErrors = v[3]; 226 this.vRecoveredSyntaxErrors = v[4]; 227 } 228 229 public int getUnitIndex() { 230 return unitIndex; 231 } 232 233 public int getParseResult() { 234 return parseResult; 235 } 236 237 public List<TCustomSqlStatement> getStatements() { 238 return slot(vStatements); 239 } 240 241 public List<TSyntaxError> getSyntaxErrors() { 242 return slot(vSyntaxErrors); 243 } 244 245 public List<TSyntaxError> getRecoveredSyntaxErrors() { 246 return slot(vRecoveredSyntaxErrors); 247 } 248 } 249 250 /** Mirror of the recorder's derived record. */ 251 public static final class DerivedRecord extends ShapeObject { 252 private final Object vStatement; 253 private final Object vSite; 254 255 DerivedRecord(Shape shape, int handle, Object[] v) { 256 super(shape, handle); 257 this.vStatement = v[0]; 258 this.vSite = v[1]; 259 } 260 261 public TCustomSqlStatement getStatement() { 262 return slot(vStatement); 263 } 264 265 public TCustomSqlStatement getSite() { 266 return slot(vSite); 267 } 268 } 269 270 /** Mirror of a relationship frozen at the end of the analysis. */ 271 public static final class FrozenRelation extends ShapeObject { 272 private final Object vRelation; 273 private final Object vTarget; 274 275 FrozenRelation(Shape shape, int handle, Object[] v) { 276 super(shape, handle); 277 this.vRelation = v[0]; 278 this.vTarget = v[1]; 279 } 280 281 public AbstractRelationship getRelation() { 282 return slot(vRelation); 283 } 284 285 public RelationshipElement getTarget() { 286 return slot(vTarget); 287 } 288 } 289}