001package gudusoft.gsqlparser.dlineage.dataflow.model; 002 003import java.util.Arrays; 004import java.util.HashSet; 005import java.util.Set; 006 007import gudusoft.gsqlparser.EDbVendor; 008import gudusoft.gsqlparser.dlineage.dataflow.listener.DataFlowHandleListener; 009 010public class Option implements Cloneable { 011 012 private EDbVendor vendor; 013 private EDbVendor powerQueryInnerVendor; 014 private DataFlowHandleListener handleListener; 015 private boolean simpleOutput; 016 private boolean textFormat = false; 017 private boolean showJoin = false; 018 private boolean ignoreRecordSet = false; 019 private boolean ignoreTemporaryTable = false; 020 private boolean ignoreTopSelect = false; 021 private boolean ignoreUnusedSynonym = true; 022 private boolean showCallRelation = false; 023 private boolean simpleShowFunction = false; 024 private boolean simpleShowSynonym = false; 025 private boolean simpleShowUdfFunctionOnly = false; 026 private boolean simpleShowCursor = false; 027 private boolean simpleShowVariable = false; 028 private boolean simpleShowTopSelectResultSet = false; 029 private boolean linkOrphanColumnToFirstTable = false; 030 private boolean ignoreCoordinate = false; 031 private boolean transform = false; 032 private boolean transformCoordinate = false; 033 private boolean showImplicitSchema = false; 034 private boolean showCountTableColumn = true; 035 private boolean showConstantTable = false; 036 private boolean showCaseWhenAsDirect = true; 037 private String filePathDatabase; 038 private String filePathSchema; 039 private long startId = 0; 040 private boolean output = true; 041 private boolean traceSQL = false; 042 private boolean traceProcedure = false; 043 private int parallel = Runtime.getRuntime().availableProcessors() / 2; 044 private String defaultServer; 045 private String defaultDatabase; 046 private String defaultSchema; 047 private boolean showERDiagram = false; 048 private Set<ResultSetType> targetResultSetTypes = new HashSet<ResultSetType>(); 049 private Set<String> filterRelationTypes = new HashSet<String>(); 050 private Set<String> simpleShowRelationTypes = new HashSet<String>(); 051 private boolean sqlflowIgnoreFunction = false; 052 053 private Set<String> excludedProcedureNames = new HashSet<String>(); 054 055 /** 056 * Wildcard patterns to exclude procedures from analysis. 057 * <p> 058 * Supports the following wildcard characters: 059 * <ul> 060 * <li><code>*</code> - Matches any sequence of characters (e.g., <code>SCHEMA1.*</code> matches all procedures in SCHEMA1)</li> 061 * <li><code>?</code> - Matches any single character (e.g., <code>SCHEMA?.PROC?</code> matches SCHEMA1.PROC1, SCHEMA2.PROC2, etc.)</li> 062 * <li><code>.</code> - Reserved as schema/procedure name separator (e.g., <code>SCHEMA.PROC</code> matches a two-segment qualified name)</li> 063 * </ul> 064 * <p> 065 * Examples: 066 * <ul> 067 * <li><code>"SCHEMA1.*"</code> - Excludes all procedures in SCHEMA1</li> 068 * <li><code>"*.SP_*"</code> - Excludes all procedures starting with SP_ in any schema</li> 069 * <li><code>"*_TEST"</code> - Excludes all procedures ending with _TEST in any schema</li> 070 * <li><code>"SCHEMA?.PROC?"</code> - Excludes procedures like SCHEMA1.PROC1, SCHEMA2.PROC2, etc.</li> 071 * <li><code>"DB.SCHEMA.PROC"</code> - Excludes a specific three-segment procedure</li> 072 * </ul> 073 * <p> 074 * Note: Pattern matching is case-insensitive. Quoted identifiers (double quotes, square brackets, backticks, single quotes) 075 * will be automatically stripped before matching. 076 */ 077 private Set<String> excludedProcedurePatterns = new HashSet<String>(); 078 private boolean showCandidateTable = true; 079 private boolean ignoreInsertIntoValues = true; 080 private boolean normalizeOutput = false; 081 /* 082 * Whether to trace all table positions. Default is false. 083 */ 084 private boolean traceTablePosition = false; 085 086 private boolean enablePipelinedStitching = true; 087 private int maxPipelinedExpansionDepth = 8; 088 private int maxStitchedSourcesPerColumn = 64; 089 090 private AnalyzeMode analyzeMode; 091 092 public EDbVendor getVendor() { 093 return vendor; 094 } 095 096 public void setVendor(EDbVendor vendor) { 097 this.vendor = vendor; 098 } 099 100 /** 101 * Explicit SQL dialect for the inner SQL embedded in Power Query 102 * {@code Value.NativeQuery()} calls and for navigation-chain synthetic 103 * SELECTs. When set, this takes precedence over the connector-based 104 * inference performed by {@code TPowerQueryAnalyzer}; when {@code null} 105 * (default), inference is used. 106 */ 107 public EDbVendor getPowerQueryInnerVendor() { 108 return powerQueryInnerVendor; 109 } 110 111 public void setPowerQueryInnerVendor(EDbVendor powerQueryInnerVendor) { 112 this.powerQueryInnerVendor = powerQueryInnerVendor; 113 } 114 115 public DataFlowHandleListener getHandleListener() { 116 return handleListener; 117 } 118 119 public void setHandleListener(DataFlowHandleListener handleListener) { 120 this.handleListener = handleListener; 121 } 122 123 public boolean isSimpleOutput() { 124 return simpleOutput; 125 } 126 127 public void setSimpleOutput(boolean simpleOutput) { 128 this.simpleOutput = simpleOutput; 129 } 130 131 public boolean isTextFormat() { 132 return textFormat; 133 } 134 135 public void setTextFormat(boolean textFormat) { 136 this.textFormat = textFormat; 137 } 138 139 public boolean isShowJoin() { 140 return showJoin; 141 } 142 143 public void setShowJoin(boolean showJoin) { 144 this.showJoin = showJoin; 145 } 146 147 /** 148 * When true, every UNRESOLVED / PARSE_ERROR dynamic-SQL site is also mirrored into an 149 * {@link ErrorInfo} (type {@link ErrorInfo#DYNAMIC_SQL_UNRESOLVED}) so legacy callers reading 150 * {@code getErrorMessages()} can see them. Default false, so existing callers are unaffected; 151 * the structured list is always available via {@code DataFlowAnalyzer.getDynamicSqlSites()}. 152 */ 153 private boolean reportDynamicSqlSitesAsErrors = false; 154 155 public boolean isReportDynamicSqlSitesAsErrors() { 156 return reportDynamicSqlSitesAsErrors; 157 } 158 159 public void setReportDynamicSqlSitesAsErrors(boolean reportDynamicSqlSitesAsErrors) { 160 this.reportDynamicSqlSitesAsErrors = reportDynamicSqlSitesAsErrors; 161 } 162 163 public boolean isIgnoreRecordSet() { 164 return ignoreRecordSet; 165 } 166 167 public void setIgnoreRecordSet(boolean ignoreRecordSet) { 168 this.ignoreRecordSet = ignoreRecordSet; 169 } 170 171 public boolean isLinkOrphanColumnToFirstTable() { 172 return linkOrphanColumnToFirstTable; 173 } 174 175 public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) { 176 this.linkOrphanColumnToFirstTable = linkOrphanColumnToFirstTable; 177 } 178 179 public boolean isIgnoreCoordinate() { 180 return ignoreCoordinate; 181 } 182 183 public void setIgnoreCoordinate(boolean ignoreCoordinate) { 184 this.ignoreCoordinate = ignoreCoordinate; 185 } 186 187 public boolean isTransform() { 188 return transform; 189 } 190 191 public void setTransform(boolean transform) { 192 this.transform = transform; 193 } 194 195 public boolean isTransformCoordinate() { 196 return transformCoordinate; 197 } 198 199 public void setTransformCoordinate(boolean transformCoordinate) { 200 this.transformCoordinate = transformCoordinate; 201 } 202 203 public boolean isSimpleShowFunction() { 204 return simpleShowFunction; 205 } 206 207 public void setSimpleShowFunction(boolean simpleShowFunction) { 208 this.simpleShowFunction = simpleShowFunction; 209 } 210 211 public boolean isSimpleShowSynonym() { 212 return simpleShowSynonym; 213 } 214 215 public void setSimpleShowSynonym(boolean simpleShowSynonym) { 216 this.simpleShowSynonym = simpleShowSynonym; 217 } 218 219 public boolean isSimpleShowTopSelectResultSet() { 220 return simpleShowTopSelectResultSet; 221 } 222 223 public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) { 224 this.simpleShowTopSelectResultSet = simpleShowTopSelectResultSet; 225 } 226 227 public boolean isShowImplicitSchema() { 228 return showImplicitSchema; 229 } 230 231 public void setShowImplicitSchema(boolean showImplicitSchema) { 232 this.showImplicitSchema = showImplicitSchema; 233 } 234 235 public boolean isShowCountTableColumn() { 236 return showCountTableColumn; 237 } 238 239 public void setShowCountTableColumn(boolean showCountTableColumn) { 240 this.showCountTableColumn = showCountTableColumn; 241 } 242 243 public boolean isShowConstantTable() { 244 return showConstantTable; 245 } 246 247 public void setShowConstantTable(boolean showConstantTable) { 248 this.showConstantTable = showConstantTable; 249 } 250 251 public long getStartId() { 252 return startId; 253 } 254 255 public void setStartId(long startId) { 256 this.startId = startId; 257 } 258 259 public boolean isOutput() { 260 return output; 261 } 262 263 public void setOutput(boolean output) { 264 this.output = output; 265 } 266 267 public int getParallel() { 268 return parallel; 269 } 270 271 public void setParallel(int parallel) { 272 this.parallel = parallel; 273 } 274 275 public boolean isTraceSQL() { 276 return traceSQL; 277 } 278 279 public void setTraceSQL(boolean traceSQL) { 280 this.traceSQL = traceSQL; 281 } 282 283 public boolean isIgnoreTopSelect() { 284 return ignoreTopSelect; 285 } 286 287 public void setIgnoreTopSelect(boolean ignoreTopSelect) { 288 this.ignoreTopSelect = ignoreTopSelect; 289 } 290 291 public void setShowCallRelation(boolean showCallRelation) { 292 this.showCallRelation = showCallRelation; 293 } 294 295 public boolean isShowCallRelation() { 296 return showCallRelation; 297 } 298 299 public String getFilePathDatabase() { 300 return filePathDatabase; 301 } 302 303 public void setFilePathDatabase(String filePathDatabase) { 304 this.filePathDatabase = filePathDatabase; 305 } 306 307 public String getFilePathSchema() { 308 return filePathSchema; 309 } 310 311 public void setFilePathSchema(String filePathSchema) { 312 this.filePathSchema = filePathSchema; 313 } 314 315 public String getDefaultServer() { 316 return defaultServer; 317 } 318 319 public void setDefaultServer(String defaultServer) { 320 this.defaultServer = defaultServer; 321 } 322 323 public String getDefaultDatabase() { 324 return defaultDatabase; 325 } 326 327 public void setDefaultDatabase(String defaultDatabase) { 328 this.defaultDatabase = defaultDatabase; 329 } 330 331 public String getDefaultSchema() { 332 return defaultSchema; 333 } 334 335 public void setDefaultSchema(String defaultSchema) { 336 this.defaultSchema = defaultSchema; 337 } 338 339 public boolean isShowERDiagram() { 340 return showERDiagram; 341 } 342 343 public void setShowERDiagram(boolean showERDiagram) { 344 this.showERDiagram = showERDiagram; 345 } 346 347 public boolean isIgnoreTemporaryTable() { 348 return ignoreTemporaryTable; 349 } 350 351 public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) { 352 this.ignoreTemporaryTable = ignoreTemporaryTable; 353 } 354 355 public void showResultSetTypes(ResultSetType... types) { 356 if(types!=null) { 357 targetResultSetTypes.addAll(Arrays.asList(types)); 358 } 359 } 360 361 public void showResultSetTypes(String... types) { 362 if (types != null) { 363 for (String type : types) { 364 ResultSetType resultSetType = ResultSetType.of(type); 365 if (resultSetType != null) { 366 targetResultSetTypes.add(resultSetType); 367 } 368 } 369 } 370 } 371 372 public boolean containsResultSetType(ResultSetType type) { 373 return targetResultSetTypes.contains(type); 374 } 375 376 @Override 377 public Object clone() throws CloneNotSupportedException { 378 return super.clone(); 379 } 380 381 public void filterRelationTypes(String... types) { 382 if (types != null) { 383 for (String type : types) { 384 RelationshipType relationshipType = RelationshipType.of(type); 385 if (relationshipType != null) { 386 filterRelationTypes.add(relationshipType.name()); 387 } 388 } 389 } 390 } 391 392 public Set<String> getFilterRelationTypes() { 393 return filterRelationTypes; 394 } 395 396 public boolean isSimpleShowCursor() { 397 return simpleShowCursor; 398 } 399 400 public void setSimpleShowCursor(boolean simpleShowCursor) { 401 this.simpleShowCursor = simpleShowCursor; 402 } 403 404 public boolean isSimpleShowVariable() { 405 return simpleShowVariable; 406 } 407 408 public void setSimpleShowVariable(boolean simpleShowVariable) { 409 this.simpleShowVariable = simpleShowVariable; 410 } 411 412 public boolean isSimpleShowUdfFunctionOnly() { 413 return simpleShowUdfFunctionOnly; 414 } 415 416 public void setSimpleShowUdfFunctionOnly(boolean simpleShowUdfFunctionOnly) { 417 this.simpleShowUdfFunctionOnly = simpleShowUdfFunctionOnly; 418 } 419 420 public boolean isTraceProcedure() { 421 return traceProcedure; 422 } 423 424 public void setTraceProcedure(boolean traceProcedure) { 425 this.traceProcedure = traceProcedure; 426 } 427 428 public boolean isSqlflowIgnoreFunction() { 429 return sqlflowIgnoreFunction; 430 } 431 432 public void setSqlflowIgnoreFunction(boolean sqlflowIgnoreFunction) { 433 this.sqlflowIgnoreFunction = sqlflowIgnoreFunction; 434 } 435 436 public boolean isShowCaseWhenAsDirect() { 437 return showCaseWhenAsDirect; 438 } 439 440 public void setShowCaseWhenAsDirect(boolean showCaseWhenAsDirect) { 441 this.showCaseWhenAsDirect = showCaseWhenAsDirect; 442 } 443 444 public boolean isIgnoreUnusedSynonym() { 445 return ignoreUnusedSynonym; 446 } 447 448 public void setIgnoreUnusedSynonym(boolean ignoreUnusedSynonym) { 449 this.ignoreUnusedSynonym = ignoreUnusedSynonym; 450 } 451 452 public boolean isShowCandidateTable() { 453 return showCandidateTable; 454 } 455 456 public void setShowCandidateTable(boolean showCandidateTable) { 457 this.showCandidateTable = showCandidateTable; 458 } 459 460 public Set<String> getSimpleShowRelationTypes() { 461 return simpleShowRelationTypes; 462 } 463 464 public void setSimpleShowRelationTypes(String... types) { 465 if (types != null) { 466 for (String type : types) { 467 RelationshipType relationshipType = RelationshipType.of(type); 468 if (relationshipType != null) { 469 simpleShowRelationTypes.add(relationshipType.name()); 470 } 471 } 472 } 473 } 474 475 public void setSimpleShowRelationTypes(RelationshipType... types) { 476 if (types != null) { 477 for (RelationshipType relationshipType : types) { 478 simpleShowRelationTypes.add(relationshipType.name()); 479 } 480 } 481 } 482 483 public AnalyzeMode getAnalyzeMode() { 484 return analyzeMode; 485 } 486 487 public void setAnalyzeMode(AnalyzeMode analyzeMode) { 488 this.analyzeMode = analyzeMode; 489 } 490 491 public boolean isIgnoreInsertIntoValues() { 492 return ignoreInsertIntoValues; 493 } 494 495 public void setIgnoreInsertIntoValues(boolean ignoreInsertIntoValues) { 496 this.ignoreInsertIntoValues = ignoreInsertIntoValues; 497 } 498 499 public boolean isNormalizeOutput() { 500 return normalizeOutput; 501 } 502 503 public void setNormalizeOutput(boolean normalizeOutput) { 504 this.normalizeOutput = normalizeOutput; 505 } 506 507 public boolean isTraceTablePosition() { 508 return traceTablePosition; 509 } 510 511 public void setTraceTablePosition(boolean traceTablePosition) { 512 this.traceTablePosition = traceTablePosition; 513 } 514 515 public boolean isEnablePipelinedStitching() { 516 return enablePipelinedStitching; 517 } 518 519 public void setEnablePipelinedStitching(boolean enablePipelinedStitching) { 520 this.enablePipelinedStitching = enablePipelinedStitching; 521 } 522 523 public int getMaxPipelinedExpansionDepth() { 524 return maxPipelinedExpansionDepth; 525 } 526 527 public void setMaxPipelinedExpansionDepth(int maxPipelinedExpansionDepth) { 528 this.maxPipelinedExpansionDepth = maxPipelinedExpansionDepth; 529 } 530 531 public int getMaxStitchedSourcesPerColumn() { 532 return maxStitchedSourcesPerColumn; 533 } 534 535 public void setMaxStitchedSourcesPerColumn(int maxStitchedSourcesPerColumn) { 536 this.maxStitchedSourcesPerColumn = maxStitchedSourcesPerColumn; 537 } 538 539 public Set<String> getExcludedProcedureNames() { 540 return excludedProcedureNames; 541 } 542 543 public void setExcludedProcedureNames(Set<String> excludedProcedureNames) { 544 this.excludedProcedureNames = excludedProcedureNames; 545 } 546 547 public void addExcludedProcedureName(String name) { 548 if (name != null && !name.isEmpty()) { 549 this.excludedProcedureNames.add(name); 550 } 551 } 552 553 public void addExcludedProcedureNames(String... names) { 554 if (names != null) { 555 for (String name : names) { 556 addExcludedProcedureName(name); 557 } 558 } 559 } 560 561 /** 562 * @see #excludedProcedurePatterns 563 */ 564 public Set<String> getExcludedProcedurePatterns() { 565 return excludedProcedurePatterns; 566 } 567 568 /** 569 * @see #excludedProcedurePatterns 570 */ 571 public void setExcludedProcedurePatterns(Set<String> excludedProcedurePatterns) { 572 this.excludedProcedurePatterns = excludedProcedurePatterns; 573 } 574 575 /** 576 * Adds a wildcard pattern to exclude procedures from analysis. 577 * @param pattern A wildcard pattern (e.g., "SCHEMA1.*", "*.SP_*", "*_TEST") 578 * @see #excludedProcedurePatterns 579 */ 580 public void addExcludedProcedurePattern(String pattern) { 581 if (pattern != null && !pattern.isEmpty()) { 582 this.excludedProcedurePatterns.add(pattern); 583 } 584 } 585 586 /** 587 * Adds multiple wildcard patterns to exclude procedures from analysis. 588 * @param patterns Variable number of wildcard patterns 589 * @see #excludedProcedurePatterns 590 */ 591 public void addExcludedProcedurePatterns(String... patterns) { 592 if (patterns != null) { 593 for (String pattern : patterns) { 594 addExcludedProcedurePattern(pattern); 595 } 596 } 597 } 598 599}