blob: 03f41fe2affc00185dc45dcf6a60c3e300973a5e [file] [log] [blame]
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -07001function AsterixDBConnection(configuration) {
2 this._properties = {};
3 this._properties["dataverse"] = "";
4 this._properties["mode"] = "synchronous";
5
6 // This is a demo setup related fix. Enabled by proxy to Asterix REST API.
7 this._properties["endpoint_root"] = "/";
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -08008
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -07009 var configuration = arguments || {};
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080010
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070011 for (var key in configuration) {
12 this._properties[key] = configuration[key];
13 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080014
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070015 return this;
16}
17
18
19AsterixDBConnection.prototype.dataverse = function(dataverseName) {
20 this._properties["dataverse"] = dataverseName;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080021
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070022 return this;
23};
24
25
26AsterixDBConnection.prototype.query = function(statements, successFn, mode) {
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070027 if ( typeof statements === 'string') {
28 statements = [ statements ];
29 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080030
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070031 var m = typeof mode ? mode : "synchronous";
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080032
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070033 var query = "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n");
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080034
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070035 this._api(
36 {
37 "query" : query,
38 "mode" : m
39 },
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080040 successFn,
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070041 "query"
42 );
43
44 return this;
45};
46
47
48AsterixDBConnection.prototype.query_status = function(data, successFn) {
49
50 this._api(
51 data,
52 successFn,
53 "query/status"
54 );
55
56 return this;
57};
58
59
60AsterixDBConnection.prototype.query_result = function(data, successFn) {
61 this._api(
62 data,
63 successFn,
64 "query/result"
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080065 );
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070066
67 return this;
68};
69
70
71AsterixDBConnection.prototype.ddl = function(statements, successFn) {
72 if ( typeof statements === 'string') {
73 statements = [ statements ];
74 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080075
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070076 this._api(
77 {
78 "ddl" : "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
79 },
80 successFn,
81 "ddl"
82 );
83}
84
85
86AsterixDBConnection.prototype.update = function(statements, successFn) {
87 if ( typeof statements === 'string') {
88 statements = [ statements ];
89 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -080090
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -070091 this._api(
92 {
93 "statements" : "use dataverse " + this._properties["dataverse"] + ";\n" + statements.join("\n")
94 },
95 successFn,
96 "update"
97 );
98}
99
100
101AsterixDBConnection.prototype._api = function(json, onSuccess, endpoint) {
102 var success_fn = onSuccess;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800103 var endpoint_url = this._properties["endpoint_root"] + endpoint;
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700104
105 $.ajax({
106 type: 'GET',
107 url: endpoint_url,
108 data : json,
109 dataType: "json",
110 success: function(data) {
111 success_fn(data);
112 },
113 error: function(xhr, status, error) {
114 }
115 });
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800116
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700117 return this;
118};
119
120
121// Asterix Expressions - Base
122function AExpression () {
123
124 this._properties = {};
125 this._success = function() {};
126
127 if (arguments.length == 1) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800128 this._properties["value"] = arguments[0];
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700129 }
130
131 return this;
132}
133
134
135AExpression.prototype.bind = function(options) {
136 var options = options || {};
137
138 if (options.hasOwnProperty("success")) {
139 this._success = options["success"];
140 }
141
142 if (options.hasOwnProperty("return")) {
143 this._properties["return"] = " return " + options["return"].val();
144 }
145};
146
147
148AExpression.prototype.run = function(successFn) {
149 return this;
150};
151
152
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800153AExpression.prototype.val = function() {
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700154
155 var value = "";
156
157 // If there is a dataverse defined, provide it.
158 if (this._properties.hasOwnProperty("dataverse")) {
159 value += "use dataverse " + this._properties["dataverse"] + ";\n";
160 };
161
162 if (this._properties.hasOwnProperty("value")) {
163 value += this._properties["value"].toString();
164 }
165
166 return value;
167};
168
169
170// @param expressionValue [String]
171AExpression.prototype.set = function(expressionValue) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800172 this._properties["value"] = expressionValue;
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700173 return this;
174};
175
176
177// AQL Statements
178// SingleStatement ::= DataverseDeclaration
179// | FunctionDeclaration
180// | CreateStatement
181// | DropStatement
182// | LoadStatement
183// | SetStatement
184// | InsertStatement
185// | DeleteStatement
186// | Query
187function InsertStatement(quantifiedName, query) {
188 AExpression.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800189
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700190 var innerQuery = "";
191 if (query instanceof AExpression) {
192 innerQuery = query.val();
193 } else if (typeof query == "object" && Object.getPrototypeOf( query ) === Object.prototype ) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800194
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700195 var insertStatements = [];
196 for (querykey in query) {
197 if (query[querykey] instanceof AExpression) {
198 insertStatements.push('"' + querykey + '" : ' + query[querykey].val());
199 } else if (typeof query[querykey] == "string") {
200 insertStatements.push('"' + querykey + '" : ' + query[querykey]);
201 } else {
202 insertStatements.push('"' + querykey + '" : ' + query[querykey].toString());
203 }
204 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800205
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700206 innerQuery = "{" + insertStatements.join(', ') + "}";
207 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800208
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700209 var statement = "insert into dataset " + quantifiedName + "(" + innerQuery + ");";
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800210
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700211 AExpression.prototype.set.call(this, statement);
212
213 return this;
214}
215
216InsertStatement.prototype = Object.create(AExpression.prototype);
217InsertStatement.prototype.constructor = InsertStatement;
218
219
220// Delete Statement
221// DeleteStatement ::= "delete" Variable "from" "dataset" QualifiedName ( "where" Expression )?
222function DeleteStatement (variable, quantifiedName, whereExpression) {
223 AExpression.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800224
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700225 var statement = "delete " + variable + " from dataset " + quantifiedName;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800226
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700227 if (whereExpression instanceof AExpression) {
228 statement += " where " + whereExpression.val();
229 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800230
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700231 AExpression.prototype.set.call(this, statement);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800232
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700233 return this;
234}
235
236DeleteStatement.prototype = Object.create(AExpression.prototype);
237DeleteStatement.prototype.constructor = DeleteStatement;
238
239// SetStatement
240//
241// Grammar
242// "set" Identifier StringLiteral
243function SetStatement (identifier, stringLiteral) {
244 AExpression.call(this);
245
246 var statement = "set " + identifier + ' "' + stringLiteral + '";';
247
248 AExpression.prototype.set.call(this, statement);
249
250 return this;
251}
252
253SetStatement.prototype = Object.create(AExpression.prototype);
254SetStatement.prototype.constructor = SetStatement;
255
256
257// Other Expressions
258
259// FunctionExpression
260// Parent: AsterixExpression
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800261//
262// @param options [Various],
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700263// @key function [String], a function to be applid to the expression
264// @key expression [AsterixExpression or AQLClause] an AsterixExpression/Clause to which the fn will be applied
265function FunctionExpression() {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800266
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700267 // Initialize superclass
268 AExpression.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800269
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700270 this._properties["function"] = "";
271 this._properties["expressions"] = [];
272
273 // Check for fn/expression input
274 if (arguments.length >= 2 && typeof arguments[0] == "string") {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800275
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700276 this._properties["function"] = arguments[0];
277
278 for (i = 1; i < arguments.length; i++) {
279 if (arguments[i] instanceof AExpression || arguments[i] instanceof AQLClause) {
280 this._properties["expressions"].push(arguments[i]);
281 } else {
282 this._properties["expressions"].push(new AExpression(arguments[i]));
283 }
284 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800285 }
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700286
287 // Return FunctionCallExpression object
288 return this;
289}
290
291
292FunctionExpression.prototype = Object.create(AExpression.prototype);
293FunctionExpression.prototype.constructor = FunctionExpression;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800294
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700295
296FunctionExpression.prototype.val = function () {
297 var fn_args = [];
298 for (var i = 0; i < this._properties["expressions"].length; i++) {
299 fn_args.push(this._properties["expressions"][i].val());
300 }
301
302 return this._properties["function"] + "(" + fn_args.join(", ") + ")";
303};
304
305
306// FLWOGRExpression
307//
308// FLWOGRExpression ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
309function FLWOGRExpression (options) {
310 // Initialize superclass
311 AExpression.call(this);
312
313 this._properties["clauses"] = [];
314 this._properties["minSize"] = 0;
315
316 // Bind options and return
317 this.bind(options);
318 return this;
319}
320
321
322FLWOGRExpression.prototype = Object.create(AExpression.prototype);
323FLWOGRExpression.prototype.constructor = FLWOGRExpression;
324
325
326FLWOGRExpression.prototype.bind = function(options) {
327 AExpression.prototype.bind.call(this, options);
328
329 var options = options || {};
330
331 if (options instanceof SetStatement) {
332 this._properties["clauses"].push(options);
333 this._properties["minSize"] += 1;
334 }
335
336 if (this._properties["clauses"].length <= this._properties["minSize"]) {
337 // Needs to start with for or let clause
338 if (options instanceof ForClause || options instanceof LetClause) {
339 this._properties["clauses"].push(options);
340 }
341 } else {
342 if (options instanceof AQLClause) {
343 this._properties["clauses"].push(options);
344 }
345 }
346
347 return this;
348};
349
350
351FLWOGRExpression.prototype.val = function() {
352 var value = AExpression.prototype.val.call(this);
353
354 var clauseValues = [];
355 for (var c in this._properties["clauses"]) {
356 clauseValues.push(this._properties["clauses"][c].val());
357 }
358
359 return value + clauseValues.join("\n");// + ";";
360};
361
362// Pretty Expression Shorthand
363
364FLWOGRExpression.prototype.ReturnClause = function(expression) {
365 return this.bind(new ReturnClause(expression));
366};
367
368FLWOGRExpression.prototype.ForClause = function() {
369 return this.bind(new ForClause(Array.prototype.slice.call(arguments)));
370};
371
372FLWOGRExpression.prototype.LetClause = function() {
373 return this.bind(new LetClause(Array.prototype.slice.call(arguments)));
374};
375
376FLWOGRExpression.prototype.WhereClause = function() {
377 return this.bind(new WhereClause(Array.prototype.slice.call(arguments)));
378};
379
380FLWOGRExpression.prototype.and = function() {
381 var args = Array.prototype.slice.call(arguments);
382 args.push(true);
383 return this.bind(new WhereClause().and(args));
384};
385
386FLWOGRExpression.prototype.or = function() {
387 var args = Array.prototype.slice.call(arguments);
388 args.push(true);
389 return this.bind(new WhereClause().or(args));
390};
391
392FLWOGRExpression.prototype.OrderbyClause = function() {
393 return this.bind(new OrderbyClause(Array.prototype.slice.call(arguments)));
394};
395
396
397FLWOGRExpression.prototype.GroupClause = function() {
398 return this.bind(new GroupClause(Array.prototype.slice.call(arguments)));
399};
400
401FLWOGRExpression.prototype.LimitClause = function() {
402 return this.bind(new LimitClause(Array.prototype.slice.call(arguments)));
403};
404
405FLWOGRExpression.prototype.DistinctClause = function() {
406 return this.bind(new DistinctClause(Array.prototype.slice.call(arguments)));
407};
408
409FLWOGRExpression.prototype.AQLClause = function() {
410 return this.bind(new AQLClause(Array.prototype.slice.call(arguments)));
411};
412
413
414// AQLClause
415//
416// Base Clause ::= ForClause | LetClause | WhereClause | OrderbyClause | GroupClause | LimitClause | DistinctClause
417function AQLClause() {
418 this._properties = {};
419 this._properties["clause"] = "";
420 this._properties["stack"] = [];
421 if (typeof arguments[0] == 'string') {
422 this._properties["clause"] = arguments[0];
423 }
424 return this;
425}
426
427AQLClause.prototype.val = function() {
428 var value = this._properties["clause"];
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800429
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700430 return value;
431};
432
433AQLClause.prototype.bind = function(options) {
434
435 if (options instanceof AQLClause) {
436 this._properties["clause"] += " " + options.val();
437 }
438
439 return this;
440};
441
442AQLClause.prototype.set = function(value) {
443 this._properties["clause"] = value;
444 return this;
445};
446
447
448// ForClause
449//
450// Grammar:
451// "for" Variable ( "at" Variable )? "in" ( Expression )
452//
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800453// @param for_variable [String], REQUIRED, first variable in clause
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700454// @param at_variable [String], NOT REQUIRED, first variable in clause
455// @param expression [AsterixExpression], REQUIRED, expression to evaluate
456function ForClause(for_variable, at_variable, expression) {
457 AQLClause.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800458
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700459 var parameters = [];
460 if (arguments[0] instanceof Array) {
461 parameters = arguments[0];
462 } else {
463 parameters = arguments;
464 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800465
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700466 this._properties["clause"] = "for " + parameters[0];
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800467
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700468 if (parameters.length == 3) {
469 this._properties["clause"] += " at " + parameters[1];
470 this._properties["clause"] += " in " + parameters[2].val();
471 } else if (parameters.length == 2) {
472 this._properties["clause"] += " in " + parameters[1].val();
473 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800474
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700475 return this;
476}
477
478ForClause.prototype = Object.create(AQLClause.prototype);
479ForClause.prototype.constructor = ForClause;
480
481
482// LetClause
483//
484// Grammar:
485// LetClause ::= "let" Variable ":=" Expression
486//
487// @param let_variable [String]
488// @param expression [AExpression]
489//
490// TODO Vigorous error checking
491function LetClause(let_variable, expression) {
492 AQLClause.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800493
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700494 var parameters = [];
495 if (arguments[0] instanceof Array) {
496 parameters = arguments[0];
497 } else {
498 parameters = arguments;
499 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800500
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700501 this._properties["clause"] = "let " + parameters[0] + " := ";
502 this._properties["clause"] += parameters[1].val();
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800503
504 return this;
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700505}
506
507LetClause.prototype = Object.create(AQLClause.prototype);
508LetClause.prototype.constructor = LetClause;
509
510
511// ReturnClause
512//
513// Grammar:
514// return [AQLExpression]
515function ReturnClause(expression) {
516 AQLClause.call(this);
517
518 this._properties["clause"] = "return ";
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800519
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700520 if (expression instanceof AExpression || expression instanceof AQLClause) {
521 this._properties["clause"] += expression.val();
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800522
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700523 } else if ( typeof expression == "object" && Object.getPrototypeOf( expression ) === Object.prototype ) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800524
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700525 this._properties["clause"] += "\n{\n";
526 var returnStatements = [];
527 for (returnValue in expression) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800528
529 if (expression[returnValue] instanceof AExpression) {
530 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue].val());
531 } else if (typeof expression[returnValue] == "string") {
532 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue]);
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700533 }
534 }
535 this._properties["clause"] += returnStatements.join(",\n");
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800536 this._properties["clause"] += "\n}";
537
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700538 } else {
539 this._properties["clause"] += new AQLClause().set(expression).val();
540 }
541
542 return this;
543}
544
545
546ReturnClause.prototype = Object.create(AQLClause.prototype);
547ReturnClause.prototype.constructor = ReturnClause;
548
549
550// WhereClause
551//
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800552// Grammar:
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700553// ::= "where" Expression
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800554//
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700555// @param expression [BooleanExpression], pushes this expression onto the stack
556function WhereClause(expression) {
557 AQLClause.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800558
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700559 this._properties["stack"] = [];
560
561 if (expression instanceof Array) {
562 this.bind(expression[0]);
563 } else {
564 this.bind(expression);
565 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800566
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700567 return this;
568}
569
570
571WhereClause.prototype = Object.create(AQLClause.prototype);
572WhereClause.prototype.constructor = WhereClause;
573
574
575WhereClause.prototype.bind = function(expression) {
576 if (expression instanceof AExpression) {
577 this._properties["stack"].push(expression);
578 }
579 return this;
580};
581
582
583WhereClause.prototype.val = function() {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800584 var value = "";
585
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700586 if (this._properties["stack"].length == 0) {
587 return value;
588 }
589
590 var count = this._properties["stack"].length - 1;
591 while (count >= 0) {
592 value += this._properties["stack"][count].val() + " ";
593 count -= 1;
594 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800595
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700596 return "where " + value;
597};
598
599
600WhereClause.prototype.and = function() {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800601
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700602 var parameters = [];
603 if (arguments[0] instanceof Array) {
604 parameters = arguments[0];
605 } else {
606 parameters = arguments;
607 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800608
609 var andClauses = [];
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700610 for (var expression in parameters) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800611
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700612 if (parameters[expression] instanceof AExpression) {
613 andClauses.push(parameters[expression].val());
614 }
615 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800616
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700617 if (andClauses.length > 0) {
618 this._properties["stack"].push(new AExpression().set(andClauses.join(" and ")));
619 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800620
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700621 return this;
622};
623
624
625WhereClause.prototype.or = function() {
626
627 var parameters = [];
628 if (arguments[0] instanceof Array) {
629 parameters = arguments[0];
630 } else {
631 parameters = arguments;
632 }
633
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800634 var orClauses = [];
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700635 for (var expression in parameters) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800636
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700637 if (parameters[expression] instanceof AExpression) {
638 orClauses.push(parameters[expression].val());
639 }
640 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800641
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700642 if (andClauses.length > 0) {
643 this._properties["stack"].push(new AExpression().set(orClauses.join(" and ")));
644 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800645
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700646 return this;
647};
648
649// LimitClause
650// Grammar:
651// LimitClause ::= "limit" Expression ( "offset" Expression )?
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800652//
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700653// @param limitExpression [REQUIRED, AQLExpression]
654// @param offsetExpression [OPTIONAL, AQLExpression]
655function LimitClause(limitExpression, offsetExpression) {
656
657 AQLClause.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800658
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700659 var parameters = [];
660 if (arguments[0] instanceof Array) {
661 parameters = arguments[0];
662 } else {
663 parameters = arguments;
664 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800665
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700666 // limitExpression required
667 this._properties["clause"] = "limit " + parameters[0].val();
668
669 // Optional: Offset
670 if (parameters.length == 2) {
671 this._properties["clause"] += " offset " + parameters[1].val();
672 }
673
674 return this;
675}
676
677LimitClause.prototype = Object.create(AQLClause.prototype);
678LimitClause.prototype.constructor = LimitClause;
679
680
681// OrderbyClause
682//
683// Grammar:
684// OrderbyClause ::= "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )*
685//
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800686// @params AQLExpressions and asc/desc strings, in any quantity. At least one required.
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700687function OrderbyClause() {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800688
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700689 AQLClause.call(this);
690
691 // At least one argument expression is required, and first should be expression
692 if (arguments.length == 0) {
693 this._properties["clause"] = null;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800694 return this;
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700695 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800696
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700697 var parameters = [];
698 if (arguments[0] instanceof Array) {
699 parameters = arguments[0];
700 } else {
701 parameters = arguments;
702 }
703
704 var expc = 0;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800705 var expressions = [];
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700706
707 while (expc < parameters.length) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800708
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700709 var expression = "";
710
711 if (parameters[expc] instanceof AExpression) {
712 expression += parameters[expc].val();
713 }
714
715 var next = expc + 1;
716 if (next < parameters.length && (parameters[next] == "asc" || parameters[next] == "desc")) {
717 expc++;
718 expression += " " + parameters[expc];
719 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800720
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700721 expressions.push(expression);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800722
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700723 expc++;
724 }
725
726 this._properties["clause"] = "order by " + expressions.join(", ");
727 return this;
728}
729
730OrderbyClause.prototype = Object.create(AQLClause.prototype);
731OrderbyClause.prototype.constructor = OrderbyClause;
732
733
734// GroupClause
735//
736// Grammar:
737// GroupClause ::= "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
738function GroupClause() {
739 AQLClause.call(this);
740
741 if (arguments.length == 0) {
742 this._properties["clause"] = null;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800743 return this;
744 }
745
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700746 var parameters = [];
747 if (arguments[0] instanceof Array) {
748 parameters = arguments[0];
749 } else {
750 parameters = arguments;
751 }
752
753 var expc = 0;
754 var expressions = [];
755 var variableRefs = [];
756 var isDecor = false;
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800757
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700758 while (expc < parameters.length) {
759
760 if (parameters[expc] instanceof AExpression) {
761
762 isDecor = false;
763 expressions.push(parameters[expc].val());
764
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800765 } else if (typeof parameters[expc] == "string") {
766
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700767 // Special keywords, decor & with
768 if (parameters[expc] == "decor") {
769 isDecor = true;
770 } else if (parameters[expc] == "with") {
771 isDecor = false;
772 expc++;
773 while (expc < parameters.length) {
774 variableRefs.push(parameters[expc]);
775 expc++;
776 }
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800777
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700778 // Variables and variable refs
779 } else {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800780
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700781 var nextc = expc + 1;
782 var expression = "";
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800783
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700784 if (isDecor) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800785 expression += "decor ";
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700786 isDecor = false;
787 }
788
789 expression += parameters[expc] + " := " + parameters[nextc].val();
790 expressions.push(expression);
791 expc++;
792 }
793 }
794
795 expc++;
796 }
797
798 this._properties["clause"] = "group by " + expressions.join(", ") + " with " + variableRefs.join(", ");
799 return this;
800}
801
802GroupClause.prototype = Object.create(AQLClause.prototype);
803GroupClause.prototype.constructor = GroupClause;
804
805
806// Quantified Expression
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800807//
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700808// Grammar
809// QuantifiedExpression ::= ( ( "some" ) | ( "every" ) ) Variable "in" Expression ( "," Variable "in" Expression )* "satisfies" Expression
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800810//
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700811// @param String some/every
812// @param [AExpression]
813// @param [Aexpression] satisfiesExpression
814function QuantifiedExpression (keyword, expressions, satisfiesExpression) {
815 AExpression.call(this);
816
817 var expression = keyword + " ";
818 var varsInExpressions = [];
819
820 for (var varInExpression in expressions) {
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800821 varsInExpressions.push(varInExpression + " in " + expressions[varInExpression].val());
822 }
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700823 expression += varsInExpressions.join(", ") + " satisfies " + satisfiesExpression.val();
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800824
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700825 AExpression.prototype.set.call(this, expression);
826
827 return this;
828}
829
830QuantifiedExpression.prototype = Object.create(AExpression.prototype);
831QuantifiedExpression.prototype.constructor = QuantifiedExpression;
832
833QuantifiedExpression.prototype.val = function() {
834 var value = AExpression.prototype.val.call(this);
Zachary Heilbron1c0bd7f2014-03-06 12:54:09 -0800835 return "(" + value + ")";
genia.likes.science@gmail.com67605862013-10-04 05:43:57 -0700836};