1 /*
2  * Copyright 2015-2018 HuntLabs.cn
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 module hunt.sql.ast.statement.SQLWithSubqueryClause;
17 
18 
19 import hunt.collection;
20 
21 import hunt.sql.ast.SQLName;
22 import hunt.sql.ast.SQLObjectImpl;
23 import hunt.sql.ast.SQLStatement;
24 import hunt.sql.visitor.SQLASTVisitor;
25 import hunt.sql.ast.statement.SQLTableSourceImpl;
26 import hunt.sql.ast.statement.SQLSelect;
27 import hunt.sql.ast.statement.SQLTableSource;
28 import hunt.sql.ast.statement.SQLSelectQueryBlock;
29 import hunt.sql.ast.SQLObject;
30 
31 public class SQLWithSubqueryClause : SQLObjectImpl {
32 
33     private bool           recursive;
34     private  List!Entry entries;
35 
36     this()
37     {
38         entries = new ArrayList!Entry();
39     }
40 
41     override public SQLWithSubqueryClause clone() {
42         SQLWithSubqueryClause x = new SQLWithSubqueryClause();
43         x.recursive = recursive;
44 
45         foreach (Entry entry ; entries) {
46             Entry entry2 = entry.clone();
47             entry2.setParent(x);
48             x.entries.add(entry2);
49         }
50 
51         return x;
52     }
53 
54     public List!Entry getEntries() {
55         return entries;
56     }
57     
58     public void addEntry(Entry entrie) {
59         if (entrie !is null) {
60             entrie.setParent(this);
61         }
62         this.entries.add(entrie);
63     }
64 
65     public bool getRecursive() {
66         return recursive;
67     }
68 
69     public void setRecursive(bool recursive) {
70         this.recursive = recursive;
71     }
72 
73     
74     override  protected void accept0(SQLASTVisitor visitor) {
75         if (visitor.visit(this)) {
76             acceptChild!(SQLWithSubqueryClause.Entry)(visitor, entries);
77         }
78         visitor.endVisit(this);
79     }
80 
81     public static class Entry : SQLTableSourceImpl {
82 
83         protected  List!SQLName columns;
84         protected SQLSelect           subQuery;
85         protected SQLStatement        returningStatement;
86 
87         this()
88         {
89             columns = new ArrayList!SQLName();
90         }
91 
92         public void cloneTo(Entry x) {
93             foreach (SQLName column ; columns) {
94                 SQLName column2 = column.clone();
95                 column2.setParent(x);
96                 x.columns.add(column2);
97             }
98 
99             if (subQuery !is null) {
100                 x.setSubQuery(subQuery.clone());
101             }
102 
103             if (returningStatement !is null) {
104                 setReturningStatement(returningStatement.clone());
105             }
106         }
107 
108         override public Entry clone() {
109             Entry x = new Entry();
110             cloneTo(x);
111             return x;
112         }
113 
114         
115         override  protected void accept0(SQLASTVisitor visitor) {
116             if (visitor.visit(this)) {
117                 acceptChild!SQLName(visitor, columns);
118                 acceptChild(visitor, subQuery);
119                 acceptChild(visitor, returningStatement);
120             }
121             visitor.endVisit(this);
122         }
123 
124         public SQLSelect getSubQuery() {
125             return subQuery;
126         }
127 
128         public void setSubQuery(SQLSelect subQuery) {
129             if (subQuery !is null) {
130                 subQuery.setParent(this);
131             }
132             this.subQuery = subQuery;
133         }
134 
135         public SQLStatement getReturningStatement() {
136             return returningStatement;
137         }
138 
139         public void setReturningStatement(SQLStatement returningStatement) {
140             if (returningStatement !is null) {
141                 returningStatement.setParent(this);
142             }
143             this.returningStatement = returningStatement;
144         }
145 
146         public List!SQLName getColumns() {
147             return columns;
148         }
149 
150         override public SQLTableSource findTableSourceWithColumn(long columnNameHash) {
151             foreach (SQLName column ; columns) {
152                 if (column.nameHashCode64() == columnNameHash) {
153                     return this;
154                 }
155             }
156 
157             if (subQuery !is null) {
158                 SQLSelectQueryBlock queryBlock = subQuery.getFirstQueryBlock();
159                 if (queryBlock !is null) {
160                     if (queryBlock.findSelectItem(columnNameHash) !is null) {
161                         return this;
162                     }
163                 }
164             }
165             return null;
166         }
167     }
168 
169     public Entry findEntry(long alias_hash) {
170         if (alias_hash == 0) {
171             return null;
172         }
173 
174         foreach (Entry entry ; entries) {
175             if (entry.aliasHashCode64() == alias_hash) {
176                 return entry;
177             }
178         }
179 
180         return null;
181     }
182 }