1 module hunt.sql.ast.SQLObjectImpl;
2 
3 import hunt.sql.ast.SQLObject;
4 import hunt.sql.visitor.SQLASTVisitor;
5 import hunt.sql.ast.SQLDataType;
6 import hunt.sql.ast.SQLExpr;
7 import hunt.collection;
8 import hunt.util.StringBuilder;
9 
10 
11 
12 abstract class SQLObjectImpl : SQLObject {
13 
14     protected SQLObject           parent;
15     protected Map!(string, Object) attributes;
16 
17     public this(){
18     }
19 
20     override public  void accept(SQLASTVisitor visitor) {
21         if (visitor is null) {
22             throw new Exception("IllegalArgument");
23         }
24 
25         visitor.preVisit(this);
26 
27         accept0(visitor);
28 
29         visitor.postVisit(this);
30     }
31 
32     protected abstract void accept0(SQLASTVisitor visitor);
33 
34     protected  void acceptChild(T = SQLObject)(SQLASTVisitor visitor, List!(T) children) {
35         if (children is null) {
36             return;
37         }
38         
39         foreach(T child ; children) {
40             acceptChild(visitor, child);
41         }
42     }
43 
44     protected  void acceptChild(SQLASTVisitor visitor, SQLObject child) {
45         if (child is null) {
46             return;
47         }
48 
49         child.accept(visitor);
50     }
51 
52     override public void output(StringBuilder buf) {
53         buf.append(super.toString());
54     }
55 
56     public override string toString() {
57         StringBuilder buf = new StringBuilder();
58         output(buf);
59         return buf.toString();
60     }
61 
62     public SQLObject getParent() {
63         return parent;
64     }
65 
66     public void setParent(SQLObject parent) {
67         this.parent = parent;
68     }
69 
70     public Map!(string, Object) getAttributes() {
71         if (attributes is null) {
72             attributes = new HashMap!(string, Object)(1);
73         }
74 
75         return attributes;
76     }
77 
78     public Object getAttribute(string name) {
79         if (attributes is null) {
80             return null;
81         }
82 
83         return attributes.get(name);
84     }
85 
86     public void putAttribute(string name, Object value) {
87         if (attributes is null) {
88             attributes = new HashMap!(string, Object)(1);
89         }
90 
91         attributes.put(name, value);
92     }
93 
94     public Map!(string, Object) getAttributesDirect() {
95         return attributes;
96     }
97     
98     // @SuppressWarnings("unchecked")
99     public void addBeforeComment(string comment) {
100         if (comment is null) {
101             return;
102         }
103         
104         if (attributes is null) {
105             attributes = new HashMap!(string, Object)(1);
106         }
107         
108         List!string comments = cast(List!string) attributes.get("format.before_comment");
109         if (comments is null) {
110             comments = new ArrayList!string(2);
111             attributes.put("format.before_comment", cast(Object)comments);
112         }
113         
114         comments.add(comment);
115     }
116     
117     // @SuppressWarnings("unchecked")
118     public void addBeforeComment(List!string comments) {
119         if (attributes is null) {
120             attributes = new HashMap!(string, Object)(1);
121         }
122         
123         List!string attrComments = cast(List!string) attributes.get("format.before_comment");
124         if (attrComments is null) {
125             attributes.put("format.before_comment", cast(Object)comments);
126         } else {
127             attrComments.addAll(comments);
128         }
129     }
130     
131     // @SuppressWarnings("unchecked")
132     public List!string getBeforeCommentsDirect() {
133         if (attributes is null) {
134             return null;
135         }
136         
137         return cast(List!string) attributes.get("format.before_comment");
138     }
139     
140     // @SuppressWarnings("unchecked")
141     public void addAfterComment(string comment) {
142         if (attributes is null) {
143             attributes = new HashMap!(string, Object)(1);
144         }
145         
146         List!string comments = cast(List!string) attributes.get("format.after_comment");
147         if (comments is null) {
148             comments = new ArrayList!string(2);
149             attributes.put("format.after_comment", cast(Object)comments);
150         }
151         
152         comments.add(comment);
153     }
154     
155     // @SuppressWarnings("unchecked")
156     public void addAfterComment(List!string comments) {
157         if (comments is null) {
158             return;
159         }
160 
161         if (attributes is null) {
162             attributes = new HashMap!(string, Object)(1);
163         }
164         
165         List!string attrComments = cast(List!string) attributes.get("format.after_comment");
166         if (attrComments is null) {
167             attributes.put("format.after_comment", cast(Object)comments);
168         } else {
169             attrComments.addAll(comments);
170         }
171     }
172     
173     // @SuppressWarnings("unchecked")
174     public List!string getAfterCommentsDirect() {
175         if (attributes is null) {
176             return null;
177         }
178         
179         return cast(List!string) attributes.get("format.after_comment");
180     }
181     
182     public bool hasBeforeComment() {
183         if (attributes is null) {
184             return false;
185         }
186 
187         List!string comments = cast(List!string) attributes.get("format.before_comment");
188 
189         if (comments is null) {
190             return false;
191         }
192         
193         return !comments.isEmpty();
194     }
195     
196     public bool hasAfterComment() {
197         if (attributes is null) {
198             return false;
199         }
200 
201         List!string comments = cast(List!string) attributes.get("format.after_comment");
202         if (comments is null) {
203             return false;
204         }
205         
206         return !comments.isEmpty();
207     }
208 
209     public SQLObject clone() {
210         throw new Exception("UnsupportedOperation");
211     }
212 
213     public SQLDataType computeDataType() {
214         return null;
215     }
216 }
217 
218 
219 class ValuesClause : SQLObjectImpl {
220 
221         private      List!SQLExpr values;
222         private  string        originalString;
223         private  int           replaceCount;
224 
225         public this(){
226             this(new ArrayList!SQLExpr());
227         }
228 
229         override public ValuesClause clone() {
230             ValuesClause x = new ValuesClause(new ArrayList!SQLExpr(this.values.size()));
231             foreach (SQLExpr v ; values) {
232                 x.addValue(v);
233             }
234             return x;
235         }
236 
237         public this(List!SQLExpr values){
238             this.values = values;
239             for (int i = 0; i < values.size(); ++i) {
240                 values.get(i).setParent(this);
241             }
242         }
243 
244         public void addValue(SQLExpr value) {
245             value.setParent(this);
246             values.add(value);
247         }
248 
249         public List!SQLExpr getValues() {
250             return values;
251         }
252 
253         override public void output(StringBuilder buf) {
254             buf.append(" VALUES (");
255             for (int i = 0, size = values.size(); i < size; ++i) {
256                 if (i != 0) {
257                     buf.append(", ");
258                 }
259                 values.get(i).output(buf);
260             }
261             buf.append(")");
262         }
263 
264         
265         override  protected void accept0(SQLASTVisitor visitor) {
266             if (visitor.visit(this)) {
267                 this.acceptChild!SQLExpr(visitor, values);
268             }
269 
270             visitor.endVisit(this);
271         }
272 
273         public string getOriginalString() {
274             return originalString;
275         }
276 
277         public void setOriginalString(string originalString) {
278             this.originalString = originalString;
279         }
280 
281         public int getReplaceCount() {
282             return replaceCount;
283         }
284 
285         public void incrementReplaceCount() {
286             this.replaceCount++;
287         }
288     }