001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004
005import gudusoft.gsqlparser.TCustomSqlStatement;
006import gudusoft.gsqlparser.TSourceToken;
007import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
008import gudusoft.gsqlparser.dlineage.util.Pair3;
009import gudusoft.gsqlparser.nodes.TParseTreeNode;
010import gudusoft.gsqlparser.util.SQLUtil;
011
012public class CallRelationship extends AbstractRelationship {
013
014    private String sqlHash;
015    private String sqlComment;
016    private Long procedureId;
017    private Boolean builtIn;
018        private TParseTreeNode callObject;
019        protected Pair3<Long, Long, String> startPosition;
020        protected Pair3<Long, Long, String> endPosition;
021
022    @Override
023    public RelationshipType getRelationshipType() {
024        return RelationshipType.call;
025    }
026
027    public String getSqlHash() {
028        return sqlHash;
029    }
030
031    public void setTarget(RelationshipElement<?> target) {
032        super.setTarget(target);
033        if(ModelBindingManager.getGlobalOption().isTraceSQL()) {
034            TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek());
035            this.sqlHash = ModelBindingManager.get().getSqlHash(stmt);
036            try {
037                this.sqlComment = stmt.getCommentBeforeNode();
038            } catch (Exception e) {
039            }
040        }
041        else if(ModelBindingManager.getGlobalOption().isShowComment()
042                && !ModelBindingManager.isSyntheticStmtContext()) {
043            // The label above THIS call, e.g. `--DW0403:销售发货单` above
044            // `DW_RPC_DW_NC_SO_DELIVERY;`. Not getTopStmt(): that climbs to the enclosing
045            // procedure and would give every call in the body the procedure's header. The call
046            // node itself is more precise still — `f1() + /* SECOND */ f2()` has two calls in one
047            // statement — and setCallObject usually runs BEFORE this, so it must not be undone.
048            try {
049                TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek();
050                // Bounded by the statement's own first token: a call is labelled by a comment
051                // INSIDE its statement, wherever the line breaks fall. Anything before the
052                // statement belongs to the statement, and is picked up by the fallback below.
053                String callSiteComment = (this.callObject == null) ? null
054                        : this.callObject.getCommentBeforeNode(true,
055                                stmt == null ? null : stmt.getStartToken());
056                if (SQLUtil.isEmpty(callSiteComment) && stmt != null) {
057                    callSiteComment = stmt.getCommentBeforeNode(true);
058                }
059                this.sqlComment = callSiteComment;
060            } catch (Exception e) {
061            }
062        }
063        
064                if(ModelBindingManager.getGlobalOption().isTraceProcedure()) {
065                TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek());
066                        Object model = ModelBindingManager.get().getModel(stmt);
067                        if(model instanceof Procedure) {
068                                this.procedureId = ((Procedure)model).getId();
069                        }
070                }
071    }
072
073    public String getSqlComment() {
074        return sqlComment;
075    }
076
077        public Long getProcedureId() {
078                return procedureId;
079        }
080
081    public Boolean getBuiltIn() {
082        return builtIn;
083    }
084
085    public void setBuiltIn(Boolean builtIn) {
086        this.builtIn = builtIn;
087    }
088
089        public TParseTreeNode getCallObject() {
090                return callObject;
091        }
092
093        public void setCallObject(TParseTreeNode callObject) {
094                this.callObject = callObject;
095                if (callObject != null && ModelBindingManager.getGlobalOption() != null
096                                && ModelBindingManager.getGlobalOption().isShowComment()
097                                && !ModelBindingManager.getGlobalOption().isTraceSQL()) {
098                        // The call node is the most precise site there is; prefer it over whatever the
099                        // enclosing statement had when the relationship was wired up.
100                        try {
101                                TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().isEmpty()
102                                                ? null : ModelBindingManager.getGlobalStmtStack().peek();
103                                String callSiteComment = callObject.getCommentBeforeNode(true,
104                                                stmt == null ? null : stmt.getStartToken());
105                                if (!SQLUtil.isEmpty(callSiteComment)) {
106                                        this.sqlComment = callSiteComment;
107                                }
108                        } catch (Exception e) {
109                        }
110                }
111                if (callObject != null && callObject.toString() != null) {
112                        TSourceToken startToken = callObject.getStartToken();
113                        TSourceToken endToken = callObject.getEndToken();
114                        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
115                                        ModelBindingManager.getGlobalHash());
116                        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
117                                        endToken.columnNo + SQLUtil.endTrim(endToken.getAstext()).length(), ModelBindingManager.getGlobalHash());
118                }
119        }
120
121        public Pair3<Long, Long, String> getStartPosition() {
122                return startPosition;
123        }
124
125        public Pair3<Long, Long, String> getEndPosition() {
126                return endPosition;
127        }
128
129}