1 module hunt.sql.ast.SQLOver;
2 
3 import hunt.sql.ast.SQLDataType;
4 import hunt.sql.ast.SQLObjectImpl;
5 import hunt.sql.ast.SQLExpr;
6 import hunt.sql.ast.SQLName;
7 import hunt.sql.ast.SQLOrderBy;
8 import hunt.sql.ast.SQLObject;
9 
10 import hunt.sql.visitor.SQLASTVisitor;
11 import hunt.collection;
12 
13 public class SQLOver : SQLObjectImpl {
14 
15     protected List!SQLExpr partitionBy;
16     protected SQLOrderBy          orderBy;
17 
18     // for db2
19     protected SQLName             of;
20 
21     protected SQLExpr             windowing;
22     protected WindowingType       windowingType = WindowingType.ROWS;
23 
24     protected bool             windowingPreceding;
25     protected bool             windowingFollowing;
26 
27     protected SQLExpr             windowingBetweenBegin;
28     protected bool             windowingBetweenBeginPreceding;
29     protected bool             windowingBetweenBeginFollowing;
30 
31     protected SQLExpr             windowingBetweenEnd;
32     protected bool             windowingBetweenEndPreceding;
33     protected bool             windowingBetweenEndFollowing;
34 
35     public this(){
36         partitionBy = new ArrayList!SQLExpr();
37     }
38 
39     public this(SQLOrderBy orderBy){
40         this();
41         this.setOrderBy(orderBy);
42     }
43 
44     protected override void accept0(SQLASTVisitor visitor) {
45         if (visitor.visit(this)) {
46             acceptChild!SQLExpr(visitor, this.partitionBy);
47             acceptChild(visitor, this.orderBy);
48             acceptChild(visitor, this.of);
49         }
50         visitor.endVisit(this);
51     }
52 
53     public SQLOrderBy getOrderBy() {
54         return orderBy;
55     }
56 
57     public void setOrderBy(SQLOrderBy orderBy) {
58         if (orderBy !is null) {
59             orderBy.setParent(this);
60         }
61         this.orderBy = orderBy;
62     }
63 
64     public SQLName getOf() {
65         return of;
66     }
67 
68     public void setOf(SQLName of) {
69         if (of !is null) {
70             of.setParent(this);
71         }
72         this.of = of;
73     }
74 
75     public List!SQLExpr getPartitionBy() {
76         return partitionBy;
77     }
78 
79     public SQLExpr getWindowing() {
80         return windowing;
81     }
82 
83     public void setWindowing(SQLExpr windowing) {
84         this.windowing = windowing;
85     }
86 
87     public WindowingType getWindowingType() {
88         return windowingType;
89     }
90 
91     public void setWindowingType(WindowingType windowingType) {
92         this.windowingType = windowingType;
93     }
94 
95     public bool isWindowingPreceding() {
96         return windowingPreceding;
97     }
98 
99     public void setWindowingPreceding(bool windowingPreceding) {
100         this.windowingPreceding = windowingPreceding;
101     }
102 
103     public bool isWindowingFollowing() {
104         return windowingFollowing;
105     }
106 
107     public void setWindowingFollowing(bool windowingFollowing) {
108         this.windowingFollowing = windowingFollowing;
109     }
110 
111     public SQLExpr getWindowingBetweenBegin() {
112         return windowingBetweenBegin;
113     }
114 
115     public void setWindowingBetweenBegin(SQLExpr windowingBetweenBegin) {
116         this.windowingBetweenBegin = windowingBetweenBegin;
117     }
118 
119     public bool isWindowingBetweenBeginPreceding() {
120         return windowingBetweenBeginPreceding;
121     }
122 
123     public void setWindowingBetweenBeginPreceding(bool windowingBetweenBeginPreceding) {
124         this.windowingBetweenBeginPreceding = windowingBetweenBeginPreceding;
125     }
126 
127     public bool isWindowingBetweenBeginFollowing() {
128         return windowingBetweenBeginFollowing;
129     }
130 
131     public void setWindowingBetweenBeginFollowing(bool windowingBetweenBeginFollowing) {
132         this.windowingBetweenBeginFollowing = windowingBetweenBeginFollowing;
133     }
134 
135     public SQLExpr getWindowingBetweenEnd() {
136         return windowingBetweenEnd;
137     }
138 
139     public void setWindowingBetweenEnd(SQLExpr windowingBetweenEnd) {
140         this.windowingBetweenEnd = windowingBetweenEnd;
141     }
142 
143     public bool isWindowingBetweenEndPreceding() {
144         return windowingBetweenEndPreceding;
145     }
146 
147     public void setWindowingBetweenEndPreceding(bool windowingBetweenEndPreceding) {
148         this.windowingBetweenEndPreceding = windowingBetweenEndPreceding;
149     }
150 
151     public bool isWindowingBetweenEndFollowing() {
152         return windowingBetweenEndFollowing;
153     }
154 
155     public void setWindowingBetweenEndFollowing(bool windowingBetweenEndFollowing) {
156         this.windowingBetweenEndFollowing = windowingBetweenEndFollowing;
157     }
158 
159     override public bool opEquals(Object o) {
160         if (this == o) return true;
161         if (o is null || typeid(o) == typeid(SQLOver)) return false;
162 
163         SQLOver sqlOver = cast(SQLOver) o;
164 
165         if (windowingPreceding != sqlOver.windowingPreceding) return false;
166         if (windowingFollowing != sqlOver.windowingFollowing) return false;
167         if (windowingBetweenBeginPreceding != sqlOver.windowingBetweenBeginPreceding) return false;
168         if (windowingBetweenBeginFollowing != sqlOver.windowingBetweenBeginFollowing) return false;
169         if (windowingBetweenEndPreceding != sqlOver.windowingBetweenEndPreceding) return false;
170         if (windowingBetweenEndFollowing != sqlOver.windowingBetweenEndFollowing) return false;
171         if (partitionBy !is null ? !(cast(Object)partitionBy).opEquals(cast(Object)sqlOver.partitionBy) : sqlOver.partitionBy !is null) return false;
172         if (orderBy !is null ? !(cast(Object)(orderBy)).opEquals(cast(Object)sqlOver.orderBy) : sqlOver.orderBy !is null) return false;
173         if (of !is null ? !(cast(Object)of).opEquals(cast(Object)(sqlOver.of)) : sqlOver.of !is null) return false;
174         if (windowing !is null ? !(cast(Object)windowing).opEquals(cast(Object)(sqlOver.windowing)) : sqlOver.windowing !is null) return false;
175         if (windowingType != sqlOver.windowingType) return false;
176         if (windowingBetweenBegin !is null ? !(cast(Object)windowingBetweenBegin).opEquals(cast(Object)(sqlOver.windowingBetweenBegin)) : sqlOver.windowingBetweenBegin !is null)
177             return false;
178         return windowingBetweenEnd !is null ? (cast(Object)windowingBetweenEnd).opEquals(cast(Object)(sqlOver.windowingBetweenEnd)) : sqlOver.windowingBetweenEnd is null;
179 
180     }
181 
182     override public size_t toHash() @trusted nothrow {
183         size_t result = partitionBy !is null ? (cast(Object)partitionBy).toHash() : 0;
184         result = 31 * result + (orderBy !is null ? (cast(Object)orderBy).toHash() : 0);
185         result = 31 * result + (of !is null ? (cast(Object)of).toHash() : 0);
186         result = 31 * result + (windowing !is null ? (cast(Object)windowing).toHash() : 0);
187         result = 31 * result + windowingType/*(windowingType !is null ? windowingType : 0)*/;
188         result = 31 * result + (windowingPreceding ? 1 : 0);
189         result = 31 * result + (windowingFollowing ? 1 : 0);
190         result = 31 * result + (windowingBetweenBegin !is null ? (cast(Object)windowingBetweenBegin).toHash() : 0);
191         result = 31 * result + (windowingBetweenBeginPreceding ? 1 : 0);
192         result = 31 * result + (windowingBetweenBeginFollowing ? 1 : 0);
193         result = 31 * result + (windowingBetweenEnd !is null ? (cast(Object)windowingBetweenEnd).toHash() : 0);
194         result = 31 * result + (windowingBetweenEndPreceding ? 1 : 0);
195         result = 31 * result + (windowingBetweenEndFollowing ? 1 : 0);
196         return result;
197     }
198 
199     public void cloneTo(SQLOver x) {
200         foreach (SQLExpr item ; partitionBy) {
201             SQLExpr item1 = item.clone();
202             item1.setParent(x);
203             x.partitionBy.add(item);
204         }
205 
206         if (orderBy !is null) {
207             x.setOrderBy(orderBy.clone());
208         }
209 
210         if (of !is null) {
211             x.setOf(of.clone());
212         }
213 
214         if (windowing !is null) {
215             x.setWindowing(windowing.clone());
216         }
217         x.windowingType = windowingType;
218         x.windowingPreceding = windowingPreceding;
219         x.windowingFollowing = windowingFollowing;
220 
221         if (windowingBetweenBegin !is null) {
222             x.setWindowingBetweenBegin(windowingBetweenBegin.clone());
223         }
224         x.windowingBetweenBeginPreceding = windowingBetweenBeginPreceding;
225         x.windowingBetweenBeginFollowing = windowingBetweenBeginFollowing;
226 
227         if (windowingBetweenEnd !is null) {
228             x.setWindowingBetweenEnd(windowingBetweenEnd.clone());
229         }
230         x.windowingBetweenEndPreceding = windowingBetweenEndPreceding;
231         x.windowingBetweenEndFollowing = windowingBetweenEndFollowing;
232     }
233 
234     public override SQLOver clone() {
235         SQLOver x = new SQLOver();
236         cloneTo(x);
237         return x;
238     }
239 
240     public static enum WindowingType : int {
241         ROWS = 0, RANGE =1
242     }
243 }