blob: 86cd5f03a75fde59f233c3cb9bea823437246ad3 [file] [log] [blame]
Ian Maxon032a1782015-06-30 17:10:51 -07001/*
2 * Copyright 2009-2013 by The Regents of the University of California
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * you may obtain a copy of the License from
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
genia.likes.science@gmail.comb91b577a2013-06-13 14:36:06 -070016function AsterixDBConnection(configuration) {
17 this._properties = {};
18 this._properties["dataverse"] = "";
19 this._properties["mode"] = "synchronous";
20
21 var configuration = arguments || {};
22
23 for (var key in configuration) {
24 this._properties[key] = configuration[key];
25 }
26
27 return this;
28}
29
30
31AsterixDBConnection.prototype.dataverse = function(dataverseName) {
32 this._properties["dataverse"] = dataverseName;
33
34 return this;
35};
36
37
genia.likes.science@gmail.com4a5dfe12013-07-05 07:10:00 -070038AsterixDBConnection.prototype.query = function(statements, successFn, mode) {
genia.likes.science@gmail.com3395d5b2013-07-05 00:47:11 -070039
genia.likes.science@gmail.comb91b577a2013-06-13 14:36:06 -070040 if ( typeof statements === 'string') {
41 statements = [ statements ];
42 }
43
genia.likes.science@gmail.com212a6442013-07-13 20:40:11 -070044 var m = typeof mode ? mode : "synchronous";
45
genia.likes.science@gmail.com78593d72013-07-02 06:33:39 -070046 var query = "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n");
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -070047
genia.likes.science@gmail.com3395d5b2013-07-05 00:47:11 -070048 this._api(
49 {
genia.likes.science@gmail.comb91b577a2013-06-13 14:36:06 -070050 "query" : query,
genia.likes.science@gmail.com4a5dfe12013-07-05 07:10:00 -070051 "mode" : m
genia.likes.science@gmail.comb91b577a2013-06-13 14:36:06 -070052 },
genia.likes.science@gmail.com3395d5b2013-07-05 00:47:11 -070053 successFn,
54 "http://localhost:19002/query"
55 );
genia.likes.science@gmail.comb91b577a2013-06-13 14:36:06 -070056
57 return this;
58};
59
60
genia.likes.science@gmail.com4a5dfe12013-07-05 07:10:00 -070061AsterixDBConnection.prototype.query_status = function(data, successFn) {
62
63 this._api(
64 data,
65 successFn,
66 "http://localhost:19002/query/status"
67 );
68
69 return this;
70};
71
72
73AsterixDBConnection.prototype.query_result = function(data, successFn) {
74 this._api(
75 data,
76 successFn,
77 "http://localhost:19002/query/result"
78 );
79
80 return this;
81};
82
genia.likes.science@gmail.com6686c452013-07-05 08:39:35 -070083
84AsterixDBConnection.prototype.ddl = function(statements, successFn) {
85 if ( typeof statements === 'string') {
86 statements = [ statements ];
87 }
88
89 this._api(
90 {
91 "ddl" : "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
92 },
93 successFn,
94 "http://localhost:19002/ddl"
95 );
96}
97
98
99AsterixDBConnection.prototype.update = function(statements, successFn) {
100 if ( typeof statements === 'string') {
101 statements = [ statements ];
102 }
103
104 this._api(
105 {
106 "statements" : "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
107 },
108 successFn,
109 "http://localhost:19002/update"
110 );
111}
112
113
genia.likes.science@gmail.com3395d5b2013-07-05 00:47:11 -0700114AsterixDBConnection.prototype._api = function(json, onSuccess, endpoint) {
115 var success_fn = onSuccess;
116
117 $.ajax({
118 type: 'GET',
119 url: endpoint,
120 data : json,
121 dataType: "json",
122 success: function(data) {
123 success_fn(data);
124 }
125 // TODO error:
126 });
127
128 return this;
129};
130
131
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700132function AExpression () {
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700133
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700134 this._properties = {};
135 this._success = function() {};
136
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700137 if (typeof arguments[0] == 'string') {
138 this._properties["value"] = arguments[0];
139 }
140
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700141 return this;
142}
143
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700144
145AExpression.prototype.bind = function(options) {
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700146 var options = options || {};
147
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700148 if (options.hasOwnProperty("success")) {
149 this._success = options["success"];
150 }
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700151
152 if (options.hasOwnProperty("return")) {
153 this._properties["return"] = " return " + options["return"].val();
154 }
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700155};
156
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700157
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700158AExpression.prototype.run = function(successFn) {
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700159 return this;
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700160};
161
162
163AExpression.prototype.val = function() {
164
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700165 var value = "";
166
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700167 // If there is a dataverse defined, provide it.
168 if (this._properties.hasOwnProperty("dataverse")) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700169 value += "use dataverse " + this._properties["dataverse"] + ";\n";
170 };
171
172 if (this._properties.hasOwnProperty("value")) {
173 value += this._properties["value"];
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700174 }
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700175
176 return value;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700177};
178
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700179// @param expressionValue [String]
180AExpression.prototype.set = function(expressionValue) {
181 this._properties["value"] = expressionValue;
182 return this;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700183};
184
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700185
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700186// FunctionExpression
187// Parent: AsterixExpression
188//
189// @param options [Various],
190// @key function [String], a function to be applid to the expression
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700191// @key expression [AsterixExpression or AQLClause] an AsterixExpression/Clause to which the fn will be applied
192function FunctionExpression() {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700193
194 // Initialize superclass
195 AExpression.call(this);
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700196
197 this._properties["function"] = "";
198 this._properties["expression"] = new AExpression().set("");
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700199
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700200 // Check for fn/expression input
201 if (arguments.length == 2 && typeof arguments[0] == "string" &&
202 (arguments[1] instanceof AExpression || arguments[1] instanceof AQLClause)) {
203
204 this._properties["function"] = arguments[0];
205 this._properties["expression"] = arguments[1];
206
207 }
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700208
209 // Return object
210 return this;
211}
212
213
214FunctionExpression.prototype = Object.create(AExpression.prototype);
215FunctionExpression.prototype.constructor = FunctionExpression;
216
217
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700218FunctionExpression.prototype.fn = function(fnName) {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700219
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700220 if (typeof fnName == "string") {
221 this._properties["function"] = fnName;
222 }
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700223
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700224 return this;
225};
226
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700227
228FunctionExpression.prototype.expression = function(expression) {
229 if (expression instanceof AExpression || expression instanceof AQLClause) {
230 this._properties["expression"] = expression;
231 }
232
233 return this;
234};
235
236
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700237FunctionExpression.prototype.val = function () {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700238 return this._properties["function"] + "(" + this._properties["expression"].val() + ")";
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700239};
240
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700241
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700242// FLWOGRExpression
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700243//
244// FLWOGRExpression ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700245function FLWOGRExpression (options) {
246 // Initialize superclass
247 AExpression.call(this);
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700248
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700249 this._properties["clauses"] = [];
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700250 this._properties["minSize"] = 0;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700251
252 // Bind options and return
253 this.bind(options);
254 return this;
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700255}
256
257
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700258FLWOGRExpression.prototype = Object.create(AExpression.prototype);
259FLWOGRExpression.prototype.constructor = FLWOGRExpression;
260
261
262FLWOGRExpression.prototype.bind = function(options) {
263 AExpression.prototype.bind.call(this, options);
264
265 var options = options || {};
266
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700267 if (options instanceof SetStatement) {
268 this._properties["clauses"].push(options);
269 this._properties["minSize"] += 1;
270 }
271
272 if (this._properties["clauses"].length <= this._properties["minSize"]) {
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700273 // Needs to start with for or let clause
274 if (options instanceof ForClause || options instanceof LetClause) {
275 this._properties["clauses"].push(options);
276 }
277 } else {
278 if (options instanceof AQLClause) {
279 this._properties["clauses"].push(options);
280 }
281 }
282
283 return this;
284};
285
286
287FLWOGRExpression.prototype.val = function() {
288 var value = AExpression.prototype.val.call(this);
289
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700290 var clauseValues = [];
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700291 for (var c in this._properties["clauses"]) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700292 clauseValues.push(this._properties["clauses"][c].val());
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700293 }
294
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700295 return value + clauseValues.join("\n");// + ";";
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700296};
297
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700298// Pretty Expression Shorthand
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700299
genia.likes.science@gmail.com5f425342013-06-13 13:51:26 -0700300FLWOGRExpression.prototype.ReturnClause = function(expression) {
301 return this.bind(new ReturnClause(expression));
302};
303
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700304FLWOGRExpression.prototype.ForClause = function() {
305 return this.bind(new ForClause(Array.prototype.slice.call(arguments)));
306};
307
308FLWOGRExpression.prototype.LetClause = function() {
309 return this.bind(new LetClause(Array.prototype.slice.call(arguments)));
310};
311
312FLWOGRExpression.prototype.WhereClause = function() {
313 return this.bind(new WhereClause(Array.prototype.slice.call(arguments)));
314};
315
316FLWOGRExpression.prototype.and = function() {
317 var args = Array.prototype.slice.call(arguments);
318 args.push(true);
319 return this.bind(new WhereClause().and(args));
320};
321
322FLWOGRExpression.prototype.or = function() {
323 var args = Array.prototype.slice.call(arguments);
324 args.push(true);
325 return this.bind(new WhereClause().or(args));
326};
327
328FLWOGRExpression.prototype.OrderbyClause = function() {
329 return this.bind(new OrderbyClause(Array.prototype.slice.call(arguments)));
330};
331
332
333FLWOGRExpression.prototype.GroupClause = function() {
334 return this.bind(new GroupClause(Array.prototype.slice.call(arguments)));
335};
336
337FLWOGRExpression.prototype.LimitClause = function() {
338 return this.bind(new LimitClause(Array.prototype.slice.call(arguments)));
339};
340
341FLWOGRExpression.prototype.DistinctClause = function() {
342 return this.bind(new DistinctClause(Array.prototype.slice.call(arguments)));
343};
344
345FLWOGRExpression.prototype.AQLClause = function() {
346 return this.bind(new AQLClause(Array.prototype.slice.call(arguments)));
347};
348
349
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700350// AQLClause
351//
352// Base Clause ::= ForClause | LetClause | WhereClause | OrderbyClause | GroupClause | LimitClause | DistinctClause
353function AQLClause() {
354 this._properties = {};
355 this._properties["clause"] = "";
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700356 this._properties["stack"] = [];
357 if (typeof arguments[0] == 'string') {
358 this._properties["clause"] = arguments[0];
359 }
360 return this;
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700361}
362
363AQLClause.prototype.val = function() {
364 var value = this._properties["clause"];
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700365
366 return value;
367};
368
369AQLClause.prototype.bind = function(options) {
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700370
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700371 if (options instanceof AQLClause) {
372 this._properties["clause"] += " " + options.val();
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700373 }
374
375 return this;
376};
377
genia.likes.science@gmail.com39578302013-05-31 04:42:26 -0700378AQLClause.prototype.set = function(value) {
379 this._properties["clause"] = value;
380 return this;
381};
382
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700383
384// ForClause
385//
386// Grammar:
387// "for" Variable ( "at" Variable )? "in" ( Expression )
388//
389// @param for_variable [String], REQUIRED, first variable in clause
390// @param at_variable [String], NOT REQUIRED, first variable in clause
391// @param expression [AsterixExpression], REQUIRED, expression to evaluate
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700392function ForClause(for_variable, at_variable, expression) {
393 AQLClause.call(this);
394
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700395 var parameters = [];
396 if (arguments[0] instanceof Array) {
397 parameters = arguments[0];
398 } else {
399 parameters = arguments;
400 }
401
402 this._properties["clause"] = "for " + parameters[0];
genia.likes.science@gmail.comf8cca192013-06-13 15:45:53 -0700403
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700404 if (parameters.length == 3) {
405 this._properties["clause"] += " at " + parameters[1];
406 this._properties["clause"] += " in " + parameters[2].val();
407 } else if (parameters.length == 2) {
408 this._properties["clause"] += " in " + parameters[1].val();
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700409 }
genia.likes.science@gmail.comf8cca192013-06-13 15:45:53 -0700410
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700411 return this;
412}
413
414ForClause.prototype = Object.create(AQLClause.prototype);
415ForClause.prototype.constructor = ForClause;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700416
417
418// LetClause
419//
420// Grammar:
421// LetClause ::= "let" Variable ":=" Expression
422//
423// @param let_variable [String]
424// @param expression [AExpression]
425//
426// TODO Vigorous error checking
427function LetClause(let_variable, expression) {
428 AQLClause.call(this);
429
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700430 var parameters = [];
431 if (arguments[0] instanceof Array) {
432 parameters = arguments[0];
433 } else {
434 parameters = arguments;
435 }
436
437 this._properties["clause"] = "let " + parameters[0] + " := ";
438 this._properties["clause"] += parameters[1].val();
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700439
440 return this;
441}
442
443LetClause.prototype = Object.create(AQLClause.prototype);
444LetClause.prototype.constructor = LetClause;
445
446
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700447// ReturnClause
448//
449// Grammar:
450// return [AQLExpression]
451function ReturnClause(expression) {
452 AQLClause.call(this);
453
454 this._properties["clause"] = "return ";
genia.likes.science@gmail.com5749ef92013-06-12 07:59:25 -0700455
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700456 if (expression instanceof AExpression || expression instanceof AQLClause) {
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700457 this._properties["clause"] += expression.val();
genia.likes.science@gmail.com5749ef92013-06-12 07:59:25 -0700458
459 } else if ( typeof expression == "object" && Object.getPrototypeOf( expression ) === Object.prototype ) {
460
461 // TODO Null object check
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700462
463 this._properties["clause"] += "{";
464 var returnStatements = [];
465 for (returnValue in expression) {
466
467 if (expression[returnValue] instanceof AExpression) {
genia.likes.science@gmail.comfba7cc82013-05-31 04:04:08 -0700468 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue].val());
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700469 } else if (typeof expression[returnValue] == "string") {
genia.likes.science@gmail.comfba7cc82013-05-31 04:04:08 -0700470 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue]);
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700471 }
472 }
473 this._properties["clause"] += returnStatements.join(",\n");
genia.likes.science@gmail.comf7929d82013-06-12 11:30:01 -0700474 this._properties["clause"] += "\n}";
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700475
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700476 } else {
genia.likes.science@gmail.com5749ef92013-06-12 07:59:25 -0700477 this._properties["clause"] += new AQLClause().set(expression).val();
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700478 }
479
480 return this;
481}
482
genia.likes.science@gmail.com5749ef92013-06-12 07:59:25 -0700483
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700484ReturnClause.prototype = Object.create(AQLClause.prototype);
485ReturnClause.prototype.constructor = ReturnClause;
486
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700487
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700488// WhereClause
489//
490// Grammar:
491// ::= "where" Expression
492//
493// @param expression [BooleanExpression], pushes this expression onto the stack
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700494function WhereClause(expression) {
495 AQLClause.call(this);
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700496
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700497 this._properties["stack"] = [];
498
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700499 if (expression instanceof Array) {
500 this.bind(expression[0]);
501 } else {
502 this.bind(expression);
503 }
504
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700505 return this;
506}
507
508
509WhereClause.prototype = Object.create(AQLClause.prototype);
510WhereClause.prototype.constructor = WhereClause;
511
512
513WhereClause.prototype.bind = function(expression) {
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700514 if (expression instanceof AExpression) {
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700515 this._properties["stack"].push(expression);
516 }
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700517 return this;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700518};
519
520
521WhereClause.prototype.val = function() {
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700522 var value = "";
523
524 if (this._properties["stack"].length == 0) {
525 return value;
526 }
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700527
528 var count = this._properties["stack"].length - 1;
529 while (count >= 0) {
530 value += this._properties["stack"][count].val() + " ";
531 count -= 1;
532 }
533
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700534 return "where " + value;
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700535};
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700536
537
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700538WhereClause.prototype.and = function() {
539
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700540 var parameters = [];
541 if (arguments[0] instanceof Array) {
542 parameters = arguments[0];
543 } else {
544 parameters = arguments;
545 }
546
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700547 var andClauses = [];
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700548 for (var expression in parameters) {
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700549
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700550 if (parameters[expression] instanceof AExpression) {
551 andClauses.push(parameters[expression].val());
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700552 }
553 }
554
555 if (andClauses.length > 0) {
556 this._properties["stack"].push(new AExpression().set(andClauses.join(" and ")));
557 }
558
559 return this;
560};
561
562
563WhereClause.prototype.or = function() {
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700564
565 var parameters = [];
566 if (arguments[0] instanceof Array) {
567 parameters = arguments[0];
568 } else {
569 parameters = arguments;
570 }
571
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700572 var orClauses = [];
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700573 for (var expression in parameters) {
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700574
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700575 if (parameters[expression] instanceof AExpression) {
576 orClauses.push(parameters[expression].val());
genia.likes.science@gmail.comd2f753e2013-06-12 13:51:03 -0700577 }
578 }
579
580 if (andClauses.length > 0) {
581 this._properties["stack"].push(new AExpression().set(orClauses.join(" and ")));
582 }
583
584 return this;
585};
586
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700587// LimitClause
588// Grammar:
589// LimitClause ::= "limit" Expression ( "offset" Expression )?
590//
591// @param limitExpression [REQUIRED, AQLExpression]
592// @param offsetExpression [OPTIONAL, AQLExpression]
593function LimitClause(limitExpression, offsetExpression) {
594
595 AQLClause.call(this);
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700596
597 var parameters = [];
598 if (arguments[0] instanceof Array) {
599 parameters = arguments[0];
600 } else {
601 parameters = arguments;
602 }
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700603
604 // limitExpression required
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700605 this._properties["clause"] = "limit " + parameters[0].val();
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700606
607 // Optional: Offset
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700608 if (parameters.length == 2) {
609 this._properties["clause"] += " offset " + parameters[1].val();
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700610 }
611
612 return this;
613}
614
615LimitClause.prototype = Object.create(AQLClause.prototype);
616LimitClause.prototype.constructor = LimitClause;
617
618
619// OrderbyClause
620//
621// Grammar:
622// OrderbyClause ::= "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )*
623//
624// @params AQLExpressions and asc/desc strings, in any quantity. At least one required.
625function OrderbyClause() {
626
627 AQLClause.call(this);
628
629 // At least one argument expression is required, and first should be expression
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700630 if (arguments.length == 0) {
genia.likes.science@gmail.com18f3bf22013-06-12 07:45:02 -0700631
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700632 alert("Order By Error");
633 this._properties["clause"] = null;
634 return this;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700635 }
636
637 var parameters = [];
638 if (arguments[0] instanceof Array) {
639 parameters = arguments[0];
640 } else {
641 parameters = arguments;
642 }
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700643
644 var expc = 0;
645 var expressions = [];
646
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700647 while (expc < parameters.length) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700648
649 var expression = "";
650
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700651 if (parameters[expc] instanceof AExpression) {
652 expression += parameters[expc].val();
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700653 }
654
655 var next = expc + 1;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700656 if (next < parameters.length && (parameters[next] == "asc" || parameters[next] == "desc")) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700657 expc++;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700658 expression += " " + parameters[expc];
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700659 }
660
661 expressions.push(expression);
662
663 expc++;
664 }
665
666 this._properties["clause"] = "order by " + expressions.join(", ");
667 return this;
668}
669
670OrderbyClause.prototype = Object.create(AQLClause.prototype);
671OrderbyClause.prototype.constructor = OrderbyClause;
672
673
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700674// GroupClause
675//
676// Grammar:
677// GroupClause ::= "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
678function GroupClause() {
679 AQLClause.call(this);
680
681 if (arguments.length == 0) {
682 // TODO Not sure which error to throw for an empty GroupBy but this should fail.
683 alert("Group Error");
684 this._properties["clause"] = null;
685 return this;
686 }
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700687
688 var parameters = [];
689 if (arguments[0] instanceof Array) {
690 parameters = arguments[0];
691 } else {
692 parameters = arguments;
693 }
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700694
695 var expc = 0;
696 var expressions = [];
697 var variableRefs = [];
698 var isDecor = false;
genia.likes.science@gmail.com5f425342013-06-13 13:51:26 -0700699
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700700 while (expc < parameters.length) {
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700701
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700702 if (parameters[expc] instanceof AExpression) {
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700703
704 isDecor = false;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700705 expressions.push(parameters[expc].val());
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700706
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700707 } else if (typeof parameters[expc] == "string") {
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700708
709 // Special keywords, decor & with
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700710 if (parameters[expc] == "decor") {
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700711 isDecor = true;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700712 } else if (parameters[expc] == "with") {
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700713 isDecor = false;
714 expc++;
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700715 while (expc < parameters.length) {
716 variableRefs.push(parameters[expc]);
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700717 expc++;
718 }
719
720 // Variables and variable refs
721 } else {
722
723 var nextc = expc + 1;
724 var expression = "";
725
726 if (isDecor) {
727 expression += "decor ";
728 isDecor = false;
729 }
730
genia.likes.science@gmail.comd2795fb2013-07-14 15:48:04 -0700731 expression += parameters[expc] + " := " + parameters[nextc].val();
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700732 expressions.push(expression);
733 expc++;
734 }
735 }
736
737 expc++;
738 }
739
740 this._properties["clause"] = "group by " + expressions.join(", ") + " with " + variableRefs.join(", ");
741 return this;
742}
743
744GroupClause.prototype = Object.create(AQLClause.prototype);
745GroupClause.prototype.constructor = GroupClause;
746
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700747
748// SetStatement
749//
750// Grammar
751// "set" Identifier StringLiteral
752function SetStatement (identifier, stringLiteral) {
753 AExpression.call(this);
754
755 var statement = "set " + identifier + ' "' + stringLiteral + '";';
756
757 AExpression.prototype.set.call(this, statement);
758
759 return this;
760}
761
762SetStatement.prototype = Object.create(AExpression.prototype);
763SetStatement.prototype.constructor = SetStatement;
genia.likes.science@gmail.come34c57b2013-05-31 10:15:49 -0700764
765
766// Quantified Expression
767//
768// Grammar
769// QuantifiedExpression ::= ( ( "some" ) | ( "every" ) ) Variable "in" Expression ( "," Variable "in" Expression )* "satisfies" Expression
770//
771// @param String some/every
772// @param [AExpression]
773// @param [Aexpression] satisfiesExpression
774function QuantifiedExpression (keyword, expressions, satisfiesExpression) {
775 AExpression.call(this);
776
777 var expression = keyword + " ";
778 var varsInExpressions = [];
779
780 for (var varInExpression in expressions) {
781 varsInExpressions.push(varInExpression + " in " + expressions[varInExpression].val());
782 }
783 expression += varsInExpressions.join(", ") + " satisfies " + satisfiesExpression.val();
784
785 AExpression.prototype.set.call(this, expression);
786
787 return this;
788}
789
790QuantifiedExpression.prototype = Object.create(AExpression.prototype);
791QuantifiedExpression.prototype.constructor = QuantifiedExpression;
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700792
793QuantifiedExpression.prototype.val = function() {
794 var value = AExpression.prototype.val.call(this);
795 return "(" + value + ")";
796};