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    public boolean isIgnoreRecordSet() {
148        return ignoreRecordSet;
149    }
150
151    public void setIgnoreRecordSet(boolean ignoreRecordSet) {
152        this.ignoreRecordSet = ignoreRecordSet;
153    }
154
155    public boolean isLinkOrphanColumnToFirstTable() {
156        return linkOrphanColumnToFirstTable;
157    }
158
159    public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) {
160        this.linkOrphanColumnToFirstTable = linkOrphanColumnToFirstTable;
161    }
162
163    public boolean isIgnoreCoordinate() {
164        return ignoreCoordinate;
165    }
166
167    public void setIgnoreCoordinate(boolean ignoreCoordinate) {
168        this.ignoreCoordinate = ignoreCoordinate;
169    }
170
171    public boolean isTransform() {
172        return transform;
173    }
174
175    public void setTransform(boolean transform) {
176        this.transform = transform;
177    }
178
179    public boolean isTransformCoordinate() {
180        return transformCoordinate;
181    }
182
183    public void setTransformCoordinate(boolean transformCoordinate) {
184        this.transformCoordinate = transformCoordinate;
185    }
186
187    public boolean isSimpleShowFunction() {
188        return simpleShowFunction;
189    }
190
191    public void setSimpleShowFunction(boolean simpleShowFunction) {
192        this.simpleShowFunction = simpleShowFunction;
193    }
194
195    public boolean isSimpleShowSynonym() {
196        return simpleShowSynonym;
197    }
198
199    public void setSimpleShowSynonym(boolean simpleShowSynonym) {
200        this.simpleShowSynonym = simpleShowSynonym;
201    }
202
203    public boolean isSimpleShowTopSelectResultSet() {
204        return simpleShowTopSelectResultSet;
205    }
206
207    public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) {
208        this.simpleShowTopSelectResultSet = simpleShowTopSelectResultSet;
209    }
210
211    public boolean isShowImplicitSchema() {
212        return showImplicitSchema;
213    }
214
215    public void setShowImplicitSchema(boolean showImplicitSchema) {
216        this.showImplicitSchema = showImplicitSchema;
217    }
218
219    public boolean isShowCountTableColumn() {
220        return showCountTableColumn;
221    }
222
223    public void setShowCountTableColumn(boolean showCountTableColumn) {
224        this.showCountTableColumn = showCountTableColumn;
225    }
226
227    public boolean isShowConstantTable() {
228        return showConstantTable;
229    }
230
231    public void setShowConstantTable(boolean showConstantTable) {
232        this.showConstantTable = showConstantTable;
233    }
234
235    public long getStartId() {
236        return startId;
237    }
238
239    public void setStartId(long startId) {
240        this.startId = startId;
241    }
242
243    public boolean isOutput() {
244        return output;
245    }
246
247    public void setOutput(boolean output) {
248        this.output = output;
249    }
250
251    public int getParallel() {
252        return parallel;
253    }
254
255    public void setParallel(int parallel) {
256        this.parallel = parallel;
257    }
258
259    public boolean isTraceSQL() {
260        return traceSQL;
261    }
262
263    public void setTraceSQL(boolean traceSQL) {
264        this.traceSQL = traceSQL;
265    }
266
267    public boolean isIgnoreTopSelect() {
268                return ignoreTopSelect;
269        }
270
271        public void setIgnoreTopSelect(boolean ignoreTopSelect) {
272                this.ignoreTopSelect = ignoreTopSelect;
273        }
274        
275        public void setShowCallRelation(boolean showCallRelation) {
276                this.showCallRelation = showCallRelation;
277        }
278        
279        public boolean isShowCallRelation() {
280                return showCallRelation;
281        }
282
283        public String getFilePathDatabase() {
284                return filePathDatabase;
285        }
286
287        public void setFilePathDatabase(String filePathDatabase) {
288                this.filePathDatabase = filePathDatabase;
289        }
290
291        public String getFilePathSchema() {
292                return filePathSchema;
293        }
294
295        public void setFilePathSchema(String filePathSchema) {
296                this.filePathSchema = filePathSchema;
297        }
298
299        public String getDefaultServer() {
300                return defaultServer;
301        }
302
303        public void setDefaultServer(String defaultServer) {
304                this.defaultServer = defaultServer;
305        }
306
307        public String getDefaultDatabase() {
308                return defaultDatabase;
309        }
310
311        public void setDefaultDatabase(String defaultDatabase) {
312                this.defaultDatabase = defaultDatabase;
313        }
314
315        public String getDefaultSchema() {
316                return defaultSchema;
317        }
318
319        public void setDefaultSchema(String defaultSchema) {
320                this.defaultSchema = defaultSchema;
321        }
322
323    public boolean isShowERDiagram() {
324        return showERDiagram;
325    }
326
327    public void setShowERDiagram(boolean showERDiagram) {
328        this.showERDiagram = showERDiagram;
329    }
330
331    public boolean isIgnoreTemporaryTable() {
332        return ignoreTemporaryTable;
333    }
334
335    public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) {
336        this.ignoreTemporaryTable = ignoreTemporaryTable;
337    }
338    
339    public void showResultSetTypes(ResultSetType... types) {
340        if(types!=null) {
341                targetResultSetTypes.addAll(Arrays.asList(types));
342        }
343    }
344    
345        public void showResultSetTypes(String... types) {
346                if (types != null) {
347                        for (String type : types) {
348                                ResultSetType resultSetType = ResultSetType.of(type);
349                                if (resultSetType != null) {
350                                        targetResultSetTypes.add(resultSetType);
351                                }
352                        }
353                }
354        }
355    
356    public boolean containsResultSetType(ResultSetType type) {
357        return targetResultSetTypes.contains(type);
358    }
359
360    @Override
361    public Object clone() throws CloneNotSupportedException {
362        return super.clone();
363    }
364    
365        public void filterRelationTypes(String... types) {
366                if (types != null) {
367                        for (String type : types) {
368                                RelationshipType relationshipType = RelationshipType.of(type);
369                                if (relationshipType != null) {
370                                        filterRelationTypes.add(relationshipType.name());
371                                }
372                        }
373                }
374        }
375
376        public Set<String> getFilterRelationTypes() {
377                return filterRelationTypes;
378        }
379
380    public boolean isSimpleShowCursor() {
381        return simpleShowCursor;
382    }
383
384    public void setSimpleShowCursor(boolean simpleShowCursor) {
385        this.simpleShowCursor = simpleShowCursor;
386    }
387
388    public boolean isSimpleShowVariable() {
389        return simpleShowVariable;
390    }
391
392    public void setSimpleShowVariable(boolean simpleShowVariable) {
393        this.simpleShowVariable = simpleShowVariable;
394    }
395
396    public boolean isSimpleShowUdfFunctionOnly() {
397        return simpleShowUdfFunctionOnly;
398    }
399
400    public void setSimpleShowUdfFunctionOnly(boolean simpleShowUdfFunctionOnly) {
401        this.simpleShowUdfFunctionOnly = simpleShowUdfFunctionOnly;
402    }
403
404        public boolean isTraceProcedure() {
405                return traceProcedure;
406        }
407
408        public void setTraceProcedure(boolean traceProcedure) {
409                this.traceProcedure = traceProcedure;
410        }
411
412    public boolean isSqlflowIgnoreFunction() {
413        return sqlflowIgnoreFunction;
414    }
415
416    public void setSqlflowIgnoreFunction(boolean sqlflowIgnoreFunction) {
417        this.sqlflowIgnoreFunction = sqlflowIgnoreFunction;
418    }
419
420    public boolean isShowCaseWhenAsDirect() {
421        return showCaseWhenAsDirect;
422    }
423
424    public void setShowCaseWhenAsDirect(boolean showCaseWhenAsDirect) {
425        this.showCaseWhenAsDirect = showCaseWhenAsDirect;
426    }
427
428        public boolean isIgnoreUnusedSynonym() {
429                return ignoreUnusedSynonym;
430        }
431
432        public void setIgnoreUnusedSynonym(boolean ignoreUnusedSynonym) {
433                this.ignoreUnusedSynonym = ignoreUnusedSynonym;
434        }
435
436        public boolean isShowCandidateTable() {
437                return showCandidateTable;
438        }
439
440        public void setShowCandidateTable(boolean showCandidateTable) {
441                this.showCandidateTable = showCandidateTable;
442        }
443
444        public Set<String> getSimpleShowRelationTypes() {
445                return simpleShowRelationTypes;
446        }
447
448        public void setSimpleShowRelationTypes(String... types) {
449                if (types != null) {
450                        for (String type : types) {
451                                RelationshipType relationshipType = RelationshipType.of(type);
452                                if (relationshipType != null) {
453                                        simpleShowRelationTypes.add(relationshipType.name());
454                                }
455                        }
456                }
457        }
458        
459        public void setSimpleShowRelationTypes(RelationshipType... types) {
460                if (types != null) {
461                        for (RelationshipType relationshipType : types) {
462                                simpleShowRelationTypes.add(relationshipType.name());
463                        }
464                }
465        }
466
467        public AnalyzeMode getAnalyzeMode() {
468                return analyzeMode;
469        }
470
471        public void setAnalyzeMode(AnalyzeMode analyzeMode) {
472                this.analyzeMode = analyzeMode;
473        }
474
475        public boolean isIgnoreInsertIntoValues() {
476                return ignoreInsertIntoValues;
477        }
478
479        public void setIgnoreInsertIntoValues(boolean ignoreInsertIntoValues) {
480                this.ignoreInsertIntoValues = ignoreInsertIntoValues;
481        }
482
483    public boolean isNormalizeOutput() {
484        return normalizeOutput;
485    }
486
487    public void setNormalizeOutput(boolean normalizeOutput) {
488        this.normalizeOutput = normalizeOutput;
489    }
490
491        public boolean isTraceTablePosition() {
492                return traceTablePosition;
493        }
494
495        public void setTraceTablePosition(boolean traceTablePosition) {
496                this.traceTablePosition = traceTablePosition;
497        }
498
499        public boolean isEnablePipelinedStitching() {
500                return enablePipelinedStitching;
501        }
502
503        public void setEnablePipelinedStitching(boolean enablePipelinedStitching) {
504                this.enablePipelinedStitching = enablePipelinedStitching;
505        }
506
507        public int getMaxPipelinedExpansionDepth() {
508                return maxPipelinedExpansionDepth;
509        }
510
511        public void setMaxPipelinedExpansionDepth(int maxPipelinedExpansionDepth) {
512                this.maxPipelinedExpansionDepth = maxPipelinedExpansionDepth;
513        }
514
515        public int getMaxStitchedSourcesPerColumn() {
516        return maxStitchedSourcesPerColumn;
517    }
518
519    public void setMaxStitchedSourcesPerColumn(int maxStitchedSourcesPerColumn) {
520        this.maxStitchedSourcesPerColumn = maxStitchedSourcesPerColumn;
521    }
522
523    public Set<String> getExcludedProcedureNames() {
524        return excludedProcedureNames;
525    }
526
527    public void setExcludedProcedureNames(Set<String> excludedProcedureNames) {
528        this.excludedProcedureNames = excludedProcedureNames;
529    }
530
531    public void addExcludedProcedureName(String name) {
532        if (name != null && !name.isEmpty()) {
533            this.excludedProcedureNames.add(name);
534        }
535    }
536
537    public void addExcludedProcedureNames(String... names) {
538        if (names != null) {
539            for (String name : names) {
540                addExcludedProcedureName(name);
541            }
542        }
543    }
544
545    /**
546     * @see #excludedProcedurePatterns
547     */
548    public Set<String> getExcludedProcedurePatterns() {
549        return excludedProcedurePatterns;
550    }
551
552    /**
553     * @see #excludedProcedurePatterns
554     */
555    public void setExcludedProcedurePatterns(Set<String> excludedProcedurePatterns) {
556        this.excludedProcedurePatterns = excludedProcedurePatterns;
557    }
558
559    /**
560     * Adds a wildcard pattern to exclude procedures from analysis.
561     * @param pattern A wildcard pattern (e.g., "SCHEMA1.*", "*.SP_*", "*_TEST")
562     * @see #excludedProcedurePatterns
563     */
564    public void addExcludedProcedurePattern(String pattern) {
565        if (pattern != null && !pattern.isEmpty()) {
566            this.excludedProcedurePatterns.add(pattern);
567        }
568    }
569
570    /**
571     * Adds multiple wildcard patterns to exclude procedures from analysis.
572     * @param patterns Variable number of wildcard patterns
573     * @see #excludedProcedurePatterns
574     */
575    public void addExcludedProcedurePatterns(String... patterns) {
576        if (patterns != null) {
577            for (String pattern : patterns) {
578                addExcludedProcedurePattern(pattern);
579            }
580        }
581    }
582
583}