1 var comb = require("comb"),
  2         Promise = comb.Promise,
  3         PromiseList = comb.PromiseList,
  4         hitch = comb.hitch;
  5 
  6 var escape = function(val, includeTicks) {
  7     if (val === undefined || val === null) {
  8         return 'NULL';
  9     }
 10     switch (typeof val) {
 11         case 'boolean': return (val) ? 'true' : 'false';
 12         case 'number': return val + '';
 13     }
 14 
 15     if (typeof val === 'object') {
 16         val = val.toString();
 17     }
 18 
 19     val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
 20         switch (s) {
 21             case "\0": return "\\0";
 22             case "\n": return "\\n";
 23             case "\r": return "\\r";
 24             case "\b": return "\\b";
 25             case "\t": return "\\t";
 26             case "\x1a": return "\\Z";
 27             default: return "\\" + s;
 28         }
 29     });
 30     return  includeTicks ? "'" + val + "'" : val;
 31 };
 32 
 33 var format = function(sql, params) {
 34     sql = sql.replace(/\?/g, function() {
 35         if (params.length == 0) {
 36             throw new Error('too few parameters given');
 37         }
 38         return escape(params.shift(), true);
 39     });
 40     return sql;
 41 };
 42 
 43 var sqlKeys = ["select", "update", "delete", "count", "set", "from", "where", "group", "having", "order", "limit", "offset"];
 44 var getSQLSection = function(key, sql) {
 45     var index = sqlKeys.indexOf(key);
 46     if (index != -1) {
 47         if ((sqlIndex = sql.search(key)) != -1) {
 48             var newKeys = sqlKeys.slice(index + 1), l = newKeys.length;
 49             for (var j = 0; j < l; j++) {
 50                 var newKey = newKeys[j];
 51                 if ((nextIndex = sql.search(newKey)) != -1) {
 52                     return sql.substr(sqlIndex, nextIndex - sqlIndex);
 53                 }
 54             }
 55             return sql.substr(sqlIndex, sql.length - sqlIndex);
 56         }
 57     } else {
 58         throw new Error("sql section does not exists");
 59     }
 60     return null;
 61 };
 62 
 63 var splitSQL = function(sql) {
 64     var ret = {sql : sql};
 65     sqlKeys.forEach(function(key, i) {
 66         ret[key] = getSQLSection(key, sql);
 67     });
 68     return ret;
 69 };
 70 
 71 var createSQLFromSplit = function(object) {
 72     var sql = "", keys = sqlKeys;
 73     if (object.update) {
 74         keys = keys.slice(1);
 75     } else if (object["delete"]) {
 76         keys = keys.slice(2);
 77     }
 78     keys.forEach(function(key, i) {
 79         if (object[key] != null) {
 80             if (i > 0 && sql.charAt(sql.length - 1) != ' ') {
 81                 sql += " ";
 82             }
 83             sql += object[key];
 84         }
 85     });
 86     return sql;
 87 };
 88 
 89 /**
 90  * @class Base class for all SQL database query types.
 91  * This class is an abstract class for all SQL adapter implementations.
 92  *
 93  * An instance of SQL provides methods for querying, updating and removing a datase
 94  * @name SQL
 95  * @property {String} sql the current sql query string.
 96  */
 97 module.exports = exports = comb.define(null, {
 98     instance : {
 99         /**@lends SQL.prototype*/
100 
101         sqlObject : null,
102 
103         _needLogic : false,
104 
105         table : null,
106 
107         db : null,
108 
109         constructor: function(table, db) {
110             this.sqlObject = {
111                 "select" : null,
112                 "update" : null,
113                 "delete" : null,
114                 "count" : null,
115                 "set" : null,
116                 "from" : null,
117                 "where" : null,
118                 "group" : null,
119                 "having" : null,
120                 "order" : null,
121                 "limit" : null,
122                 "offset" : null
123             };
124             this._needLogic = false;
125             this.table = table;
126             this.db = db;
127         },
128 
129         /**
130          * Clear the current query.
131          */
132         clear : function() {
133             this.sqlObject = {
134                 "select" : null,
135                 "update" : null,
136                 "delete" : null,
137                 "count" : null,
138                 "set" : null,
139                 "from" : null,
140                 "where" : null,
141                 "group" : null,
142                 "having" : null,
143                 "order" : null,
144                 "limit" : null,
145                 "offset" : null
146             };
147         },
148 
149         /**
150          * Formats and escapes query string.
151          *
152          * @function
153          * @param {String} sql the sql to format
154          * @param {Array} array of values to place in the query.
155          *
156          * @return {String} the formatted string.
157          */
158         format : format,
159 
160         _from : function(sql) {
161             var sqlObject = this.sqlObject;
162             if (!sqlObject.from) {
163                 sqlObject.from = "from " + this.table;
164             }
165             return this;
166         },
167 
168         _parseObjectAndCreateSQL : function(options) {
169             if (options) {
170                 /*if (typeof options == "string") {
171                  var args = Array.prototype.slice.call(arguments);
172                  if (args.length > 1) {
173                  var sql = args.shift;
174                  this.sql += this.format(sql, args);
175                  } else {
176                  //assume it is raw sql
177                  this.sql += options;
178                  }
179                  } else */
180                 if (typeof options == "object") {
181                     var params = [], count = 0;
182                     for (var i in options) {
183                         if (count) {
184                             var opts = {};
185                             opts[i] = options[i];
186                             this.and(opts);
187                         } else {
188                             this._createSQLFromObject(i, options[i]);
189                         }
190                         count++;
191                     }
192                 } else {
193                     throw new Error("Options must be of type string or object");
194                 }
195             }
196         },
197 
198         _createSQLFromObject : function(key, val) {
199             var params = [], count = 0, opts;
200             if (val instanceof Array) {
201                 //assume its an in
202                 opts = {};
203                 opts[key] = val;
204                 this["in"](opts);
205             } else if (typeof val === "object") {
206                 for (var j in val) {
207                     if (j in this) {
208                         opts = {};
209                         opts[key] = val[j];
210                         this[j](opts);
211                     } else {
212                         throw new Error("Operation " + j + " is not supported");
213                     }
214                 }
215             } else {
216                 //assume its equals
217                 opts = {};
218                 opts[key] = val;
219                 this.eq(opts);
220 
221             }
222             return this;
223         },
224 
225         /**
226          * Set the where clause of the query.
227          * This is different fron find in that it can be used with updates, and deletions.
228          *
229          * @example
230          * QUERYING
231          *
232          * var sql = new SQL("test", db);
233          *
234          * //select * from test where id = 1
235          * sql.where({id : 1});
236          * //select * from test where id in (1,2,3,4,5)
237          * sql.where({id : [1,2,3,4,5]});
238          * //select * from test where x != 0
239          * sql.where({x : {neq : 0}});
240          * //select distinct * from test where id = 1
241          * sql.where({id : 1}).distinct();
242          * //select * from test where a >= 'b' limit 1
243          * sql.where({a : {gte : "b"}}).limit(1);
244          * //select * from test where flag is unknown
245          * sql.where({flag : {is : "unknown"}});
246          * //select * from test where flag is not unknown
247          * sql.where({flag : {isNot : "unknown"}});
248          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
249          * sql.where({flag : {is : false}, flag2 : {isNot : "unknown"}, anotherFlag : {isNull : true}, yetAnotherFlag : {isNotNull : true}});
250          * //select * from test where firstName like 'bob' and lastName not like 'henry'
251          * sql.where({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
252          * //select * from test where firstName like 'bob' and lastName not like 'henry'
253          * sql.where({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
254          *
255          * @example
256          * UPDATES
257          *
258          * //update test set x=1 where x >= 1 and x <= 5
259          * sql.update({x : 1}).where({x : {between : [1,5]}});
260          *
261          * @example
262          * DELETIONS
263          *
264          * //delete from test where x >= 1 and x <= 5
265          * sql.remove().where({x : {between : [1,5]}});
266          *
267          * @param {Object} options See {@link SQL#find}
268          *
269          * @return {SQL} this to allow chaining of query elements.
270          */
271         where : function(options) {
272             throw new Error("Not Implemented!");
273         },
274 
275         /**
276          * Use to return particular columns from a query, i.e. select clause in sql.
277          *
278          * @example
279          * var sql = new SQL("test", db);
280          *
281          * //select a, b, c from testTable;
282          * sql.select(["a", "b", "c"]);
283          * //select a from testTable;
284          * sql.select("a");
285          * //select a from test where x = 1 and y >=1 and y <= 10
286          * sql.select("a", {x : 1, y : {between : [1,10]}});
287          *
288          * @param {String|Array} columns the columns to select
289          * @param {Object} options query {@link SQL#find}
290          *
291          * @return {SQL} this to allow chaining of query elements.
292          */
293         select : function(values, options) {
294             throw new Error("Not Implemented!");
295         },
296 
297         /**
298          * Select on dinstict results, same is distinct clause in SQL statment.
299          *
300          * @example
301          * //select distinct * from test where id = 1
302          * sql.find({id : 1}).distinct();
303          * //select distinct test.* from test inner join test2 on test.id=test2.id where test2.other = 1
304          * sql.join("test2", {id : "id"}).where({"test2.other" : 1}).select("test.*").distinct();
305          *
306          * @return {SQL} this to allow chaining of query elements.
307          */
308         distinct : function() {
309             throw new Error("Not Implemented!");
310         },
311 
312         /**
313          * Signify this SQL instance as an update statement.
314          *
315          * <p><b>Cannot be used in combination with remove, or find queries.</b></p>
316          *
317          * @example
318          * //update test set x=1
319          * sql.update({x : 1});
320          * //update test set x=1 where x >= 1 and x <= 5
321          * sql.update({x : 1}, {x : {between : [1,5]}});
322          * //update test set x=1 where x >= 1 and x <= 5
323          * sql.update({x : 1}).where({x : {between : [1,5]}});
324          * //update test set x=1 where x >= 1 and x <= 5
325          * sql.update({x : 1}).find({x : {between : [1,5]}});
326          * //update test inner join test2 on test.flag=test2.false set x=1
327          * sql.update({x : 1}).join("test2", {flag : false});
328          * @param {Object} values key value pairs of columns, and values to update.
329          * @param {Object} [query] optional query to allow limiting of rows to update {@link SQL#where}
330          *
331          * @return {SQL} this to allow chaining of query elements.
332          */
333         update : function(values, options) {
334             throw new Error("Not Implemented!");
335         },
336 
337         /**
338          *  Signify this SQL instance as a delete statement
339          *
340          *  <p><b>Cannot be used in combination with update, or find queries.</b></p>
341          *
342          * @example
343          * //delete from test
344          * sql.remove();
345          * //delete from test where x >= 1 and x <= 5
346          * sql.remove(null, {x : {between : [1,5]}});
347          * //delete from test where x >= 1 and x <= 5
348          * sql.remove().where({x : {between : [1,5]}});
349          * //delete from test where x >= 1 and x <= 5
350          * sql.remove().find({x : {between : [1,5]}});
351          * //delete test from test inner join test2 on test.flag=test2.false
352          * sql.remove().join("test2", {flag : false});
353          * //delete test, test2 from test inner join test2 on test.flag=test2.false
354          * sql.remove("test2").join("test2", {flag : false});
355          *
356          * @param {String|Array} [tables=null] Should only be used to specify the removal of items from multiple tables.
357          * @param {Object} [query] Use to limit the rows deleted {@link SQL#where}
358          *
359          * @return {SQL} this to allow chaining of query elements.
360          */
361         remove : function(values, options) {
362             throw new Error("Not Implemented!");
363         },
364 
365         /**
366          * This is a wrapper to enable using an object to query a dataset.
367          * The hash can contain the name of any querying function as a key,
368          * and the value to look for as the value. When using find it signifies
369          * this SQL instance as a query.
370          *
371          *  <p><b>Cannot be used in combination with update, or remove queries.</b></p>
372          *
373          * @example
374          *  {nameOfColumn : {queryOp : value}};
375          * @example
376          *  var sql = new SQL("test", db);
377          *
378          * //select * from test
379          * sql.find();
380          * //select * from test where id = 1;
381          * sql.find({id : 1});
382          * //select * from test where x != 0
383          * sql.find({x : {neq : 0}});
384          * //select * from test where id in (1,2,3,4,5)
385          * sql.find({id : [1,2,3,4,5]});
386          *  //select distinct * from test where id = 1
387          * sql.find({id : 1}).distinct();
388          * //select * from test where a >= 'b' limit 1
389          * sql.find({a : {gte : "b"}}).limit(1);
390          * //select * from test where flag is unknown
391          * sql.find({flag : {is : "unknown"}});
392          * //select * from test where flag is not unknown
393          * sql.find({flag : {isNot : "unknown"}});
394          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
395          * sql.find({flag : {is : false}, flag2 : {isNot : "unknown"}, anotherFlag : {isNull : true}, yetAnotherFlag : {isNotNull : true}});
396          * //select * from test where firstName like 'bob' and lastName not like 'henry'
397          * sql.find({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
398          * //select * from test where firstName like 'bob' and lastName not like 'henry'
399          * sql.find({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
400          *
401          * @param {Object} [query] query to limit result set.
402          *
403          * @return {SQL} this to allow chaining of query elements.
404          */
405         find : function(options) {
406             throw new Error("Not Implemented!");
407         },
408 
409         /**
410          * To be used with queries to specify an order of the result set.
411          *
412          * @example
413          * //select * from test order by x
414          * sql.order("x");
415          * //select * from test order by x desc
416          * sql.order({x : "desc"});
417          * //select * from test order by x, y
418          * sql.order(["x", "y"]);
419          * //select * from test order by x, y desc
420          * sql.order(["x", {y : "desc"}]);
421          * //select * from test order by x desc, y desc
422          * sql.order([{x : "desc"},{y : "desc"}]);
423          * //select * from test order by x, y, z desc
424          * sql.order("x").order("y").order({z : "desc"});
425          *
426          * @param {String|Array|Object} options see example for uses of each.
427          *
428          * @return {SQL} this to allow chaining of query elements.
429          */
430         order : function(options) {
431             throw new Error("Not Implemented!");
432         },
433 
434         /**
435          * {@link SQL#order}
436          * @param options
437          *
438          * @return {SQL} this to allow chaining of query elements.
439          */
440         orderBy : function(options) {
441             return this.order(options);
442         },
443 
444         /**
445          * Clears the order clause
446          *
447          * @return {SQL} this to allow chaining of query elements.
448          */
449         clearOrder : function() {
450             var sqlObject = this.sqlObject;
451             delete sqlObject.order;
452             return this;
453         },
454 
455         /**
456          * Use to limit the number of results returned.
457          *
458          * @example
459          * //select * from test limit 1
460          * sql.limit(1);
461          * //select * from test limit 1 offset 10
462          * sql.limit(1, 10);
463          * //select * from test where a >= 'b' limit 1
464          * sql.find({a : {gte : "b"}}).limit(1);
465          *
466          * @param {Number} limit the limit to specify on the query
467          * @param {Number} [offset] {@link SQL#offset}
468          *
469          * @return {SQL} this to allow chaining of query elements.
470          */
471         limit : function(limit, offset) {
472             throw new Error("Not Implemented!");
473         },
474 
475         /**
476          * Clear the limit clause on this SQL query
477          *
478          * @return {SQL} this to allow chaining of query elements.
479          */
480         clearLimit : function() {
481             var sqlObject = this.sqlObject;
482             delete sqlObject.limit;
483             return this;
484         },
485 
486         /**
487          * Specify an offset, offset says to skip that many rows
488          * before beginning to return rows to the client. If both
489          * offset and limit are used, then offset rows are skipped
490          * before starting to count the limit rows that are returned
491          *
492          * @example
493          * //select * from test where a >= 'b' offset 10
494          * sql.find({a : {gte : "b"}}).offset(10);
495          * @param {Number} offset the number to offset the result set by.
496          *
497          * @return {SQL} this to allow chaining of query elements.
498          */
499         offset : function(offset) {
500             throw new Error("Not Implemented!");
501         },
502 
503         /**
504          * Removes the offset clause from a query.
505          *
506          * @return {SQL} this to allow chaining of query elements.
507          */
508         clearOffset : function() {
509             var sqlObject = this.sqlObject;
510             delete sqlObject.offset;
511             return this;
512         },
513 
514         /**
515          * Perform a group operation.
516          *
517          * @example
518          * //select * from test group by name
519          * sql.group("name");
520          * //select * from test group by name, age
521          * sql.group(["name", "age"]);
522          * //select * from test group by name having name = 'bob'
523          * sql.group("name", {name : "bob"});
524          * //select * from test group by name, age having age >= 10 and age <= 20
525          * sql.group(["name", "age"], {age : {between : [10, 20]}});
526          *
527          * @param {String|Array} key specify the columns to group on.
528          * @param {Object} having specify a having clause {@link SQL#having}.
529          *
530          * @return {SQL} this to allow chaining of query elements.
531          */
532         group : function(key, options) {
533             throw new Error("Not Implemented!");
534         },
535 
536         /**
537          * Add a having clause, this is only valid on queries that contain a group clause.
538          *
539          * Once a having clause has been added all query operations will be added to the having clause.
540          *
541          * @example
542          * //select * from test group by name, age having age >= 10 and age <= 20
543          * sql.group(["name", "age"]).having({age : {between : [10, 20]}});
544          * //select * from test group by name, age having age >= 10 and age <= 20
545          * sql.group(["name", "age"]).having().find({age : {between : [10, 20]}});
546          * //select * from test group by name, age having age is null
547          * sql.group(["name", "age"]).having().isNull("age");
548          *
549          * @param {Object} [options] the query use on the having clause, same syntax as {@link SQL#find}, {@link SQL#where};
550          *
551          * @return {SQL} this to allow chaining of query elements.
552          */
553         having : function(options) {
554             throw new Error("Not Implemented!");
555         },
556 
557         /**
558          * Clear the having clause from the query.
559          *
560          * @return {SQL} this to allow chaining of query elements.
561          */
562         clearHaving : function() {
563             var sqlObject = this.sqlObject;
564             delete sqlObject.having;
565             return this;
566         },
567 
568         /**
569          * Add a logic group to a query. The query that is passed in will be wrapped in parens.
570          *
571          * @example
572          * //select * from test where (flag is not null and x = 1) or (x = 2)
573          * sql.logicGroup({flag : {isNot : null}, x : 1}).or().logicGroup({x : 2});
574          *
575          * @param {Object} query query to group as one logical group;
576          *
577          * @return {SQL} this to allow chaining of query elements.
578          */
579         logicGroup : function(options) {
580             throw new Error("Not Implemented!");
581         },
582 
583         /**
584          * Specify an is clause.
585          *
586          * @example
587          * //select * from test where flag is true
588          * sql.is({flag : true});
589          * //select * from test where flag is false
590          * sql.is({flag : false});
591          * //select * from test where flag is null
592          * sql.is({flag : null});
593          * //select * from test where flag is unknown
594          * sql.is({flag : "unknown"});
595          * //select * from test where flag is true and otherFlag is false and anotherFlag is unknown and yetAnotherFlag is null
596          * sql.is({flag : true, otherFlag : false, anotherFlag : "unknown", yetAnotherFlag : null});
597          * //select * from test where flag is unknown
598          * sql.find({flag : {is : "unknown"}});
599          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
600          * sql.is({flag : false}).isNot({flag : "unknown"}).isNull("anotherFlag").isNotNull("yetAnotherFlag
601          * //select * from test where flag is not null and flag is true or flag is false
602          * sql.isNotNull("flag").is({flag : true}).or({flag : {is : false}});
603          *
604          * @param {Object} options key value pairs to add is clauses for.
605          *
606          * @return {SQL} this to allow chaining of query elements.
607          */
608         is: function(options) {
609             throw new Error("Not Implemented")
610         },
611 
612         /**
613          * Add is not clause
614          *
615          * @example
616          *
617          * //select * from test where flag is not true
618          * sql.isNot({flag : true});
619          * //select * from test where flag is not false
620          * sql.isNot({flag : false});
621          *  //select * from test where flag is not null
622          * sql.isNot({flag : null});
623          * //select * from test where flag is not unknown
624          * sql.isNot({flag : "unknown"});
625          * //select * from test where flag is not true and otherFlag is not false and anotherFlag is not unknown and yetAnotherFlag is not null
626          * sql.isNot({flag : true, otherFlag : false, anotherFlag : "unknown", yetAnotherFlag : null});
627          * //select * from test where flag is not unknown
628          * sql.find({flag : {isNot : "unknown"}});
629          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
630          * sql.is({flag : false}).isNot({flag : "unknown"}).isNull("anotherFlag").isNotNull("yetAnotherFlag");
631          * sql.find({flag : {is : false}, flag2 : {isNot : "unknown"}, anotherFlag : {isNull : true}, yetAnotherFlag : {isNotNull : true}});
632          * //select * from test where flag is not null and flag is true or flag is false
633          * sql.isNotNull("flag").is({flag : true}).or({flag : {is : false}});
634          *
635          * @param {Object} options key value pairs to add is not clauses for.
636          *
637          * @return {SQL} this to allow chaining of query elements.
638          */
639         isNot: function(options) {
640             throw new Error("Not Implemented")
641         },
642 
643         /**
644          * Add is null check
645          *
646          * @example
647          *  //select * from test where flag is null
648          * sql.isNull("flag");
649          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
650          * sql.is({flag : false}).isNot({flag : "unknown"}).isNull("anotherFlag").isNotNull("yetAnotherFlag
651          * //select * from test where flag is not null and flag is true or flag is false
652          * sql.isNotNull("flag").is({flag : true}).or({flag : {is : false}});
653          *
654          * @param {String} options column to check is not null.
655          *
656          * @return {SQL} this to allow chaining of query elements.
657          */
658         isNull: function(options) {
659             throw new Error("Not Implemented")
660         },
661 
662         /**
663          * Check if a column is not null.
664          *
665          * @example
666          * //select * from test where flag is not null
667          * sql.isNotNull("flag");
668          * //select * from test where flag is false and flag is not unknown and anotherFlag is null and yetAnotherFlag is not null
669          * sql.is({flag : false}).isNot({flag : "unknown"}).isNull("anotherFlag").isNotNull("yetAnotherFlag
670          * //select * from test where flag is not null and flag is true or flag is false
671          * sql.isNotNull("flag").is({flag : true}).or({flag : {is : false}});
672          *
673          * @param {String} options name of column to check.
674          *
675          * @return {SQL} this to allow chaining of query elements.
676          */
677         isNotNull: function(options) {
678             throw new Error("Not Implemented")
679         },
680 
681         /**
682          * Add and operator, one does not need to call this but it is provided for clarity.
683          *
684          * @example
685          * //select * from test where x <= 1 and y >= 1
686          * sql.lte({x : 1}).gte({y : 1});
687          * sql.lte({x : 1}).and({y : { gte : 1}});
688          * sql.lte({x : 1}).and().gte({y : 1});
689          *
690          * @param {Object} [options] query to append after the and.
691          *
692          * @return {SQL} this to allow chaining of query elements.
693          */
694         and: function(options) {
695             throw new Error("Not Implemented")
696         },
697 
698         /**
699          * Use to add an or clause
700          * @example
701          * //select * from test where x <= 1 and y >= 1
702          *  sql.lte({x : 1}).or({y : {gte : 1}});
703          *  sql.lte({x : 1}).or().gte({y : 1});
704          * @param {Object} query added after the or clause
705          */
706         or: function(options) {
707             throw new Error("Not Implemented")
708         },
709 
710         /**
711          * Use to find rows that are greater than a particular value
712          *
713          * @example
714          * //select * from test where x > 0
715          *sql.gt({x : 0});
716          *sql.find({x : {gt : 0}});
717          * @param {Object} options keys values to add greater than checks for.
718          *
719          * @return {SQL} this to allow chaining of query elements.
720          */
721         gt: function(options) {
722             throw new Error("Not Implemented")
723         },
724 
725         /**
726          * Add a check for a value greater than or equal to a particular value.
727          *
728          * @example
729          * //select * from test where x >= 0
730          * sql.gte({x : 0});
731          * sql.find({x : {gte : 0}});
732          *
733          * @param {Object} options key values to add greater than or equal to checks.
734          *
735          * @return {SQL} this to allow chaining of query elements.
736          */
737         gte: function(options) {
738             throw new Error("Not Implemented")
739         },
740 
741         /**
742          * Add a check for a value less than a particular value.
743          *
744          * @example
745          * //select * from test where x < 1
746          * sql.lt({x : 1});
747          * sql.find({x : {lt : 1}});
748          * @param {Object} options key values to add less than checks.
749          *
750          * @return {SQL} this to allow chaining of query elements.
751          */
752         lt: function(options) {
753             throw new Error("Not Implemented")
754         },
755 
756         /**
757          * Add a check for a value less than or equal to a particular value.
758          *
759          * @example
760          * //select * from test where x <= 1
761          * sql.lte({x : 1});
762          * sql.find({x : {lte : 1}});
763          * @param {Object} options key values to add less than or equal to checks.
764          *
765          * @return {SQL} this to allow chaining of query elements.
766          */
767         lte: function(options) {
768             throw new Error("Not Implemented")
769         },
770 
771         /**
772          * Use to find rows that equal a particular value
773          *
774          * @example
775          * //select * from test where x = 0");
776          * sql.eq({x : 0});
777          * sql.find({x : 0});
778          * @param {Object} options object with key\<column\> and value\<value it should equal\>
779          *
780          *  @return {SQL} this to allow chaining of query elements.
781          */
782         eq: function(options) {
783             throw new Error("Not Implemented")
784         },
785 
786         /**
787          * Use to find rows that have a column that do not equal a particular value.
788          *
789          * @example
790          * //select * from test where x != 0;
791          * sql.neq({x : 0});
792          * sql.find({x : {neq : 0}});
793          *
794          * @param {Object} options key value pairs to find columns no equal to a value
795          *
796          * @return {SQL} this to allow chaining of query elements.
797          */
798         neq: function(options) {
799             throw new Error("Not Implemented")
800         },
801 
802         /**
803          * This is an alias for an inner join.
804          *
805          * @example
806          *
807          * //select * from test inner join test2 on test.id=test2.id
808          *  sql.join("test2", {id : "id"});
809          * //select * from test inner join test2 using (id, name)
810          *  sql.join("test2", ["id", "name"]);
811          *  //select * from test inner join test2 on test.id=test2.id left join test3 using (name)
812          * sql.join("test2", {id : "id"}).leftJoin("test3", ["name"]);
813          * //select * from test inner join test2 using (id, name) natural join test3
814          * sql.join("test2", ["id", "name"]).naturalJoin("test3
815          * //select * from test inner join test2 on test.id=test2.id left join test3 using (name) where x = 2 or x = 3
816          * sql.join("test2", {id : "id"}).leftJoin("test3", ["name"]).eq({x : 2}).or({x : 3});
817          *
818          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
819          * @param {Array|Object} options When an array is passed in the a using clause is used
820          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
821          *
822          * @return {SQL} this to allow chaining of query elements.
823          */
824         join : function(table, options) {
825             throw new Error("Not Implemented!");
826         },
827 
828         /**
829          * Add an inner join to another table
830          *
831          * @example
832          * //select * from test inner join test2 on test.id=test2.id
833          * sql.innerJoin("test2", {id : "id"});
834          * //select * from test inner join test2 using (id, name)
835          * sql.innerJoin("test2", ["id", "name"]);
836          *
837          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
838          * @param {Array|Object} options When an array is passed in the a using clause is used
839          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
840          *
841          * @return {SQL} this to allow chaining of query elements.
842          */
843         innerJoin: function(tableName, options) {
844             throw new Error("Not Implemented")
845         },
846 
847         /**
848          * Add a full outer join to another table
849          *
850          * @example
851          * //select * from test full outer join test2 on test.id=test2.id
852          * sql.fullOuterJoin("test2", {id : "id"});
853          * //select * from test full outer join test2 using (id, name)
854          * sql.fullOuterJoin("test2", ["id", "name"]);
855          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
856          * @param {Array|Object} options When an array is passed in the a using clause is used
857          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
858          *
859          * @return {SQL} this to allow chaining of query elements.
860          */
861         fullOuterJoin: function(tableName, options) {
862             throw new Error("Not Implemented")
863         },
864 
865         /**
866          * Add a right outer join to another table
867          *
868          * @example
869          * sql.rightOuterJoin("test2", {id : "id"});
870          * //select * from test right outer join test2 on test.id=test2.id
871          * sql.rightOuterJoin("test2", ["id", "name"]);
872          * //select * from test right outer join test2 using (id, name);
873          *
874          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
875          * @param {Array|Object} options When an array is passed in the a using clause is used
876          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
877          *
878          * @return {SQL} this to allow chaining of query elements.
879          */
880         rightOuterJoin: function(tableName, options) {
881             throw new Error("Not Implemented")
882         },
883 
884         /**
885          * Add a left outer join to another table
886          *
887          * @example
888          * //select * from test left outer join test2 on test.id=test2.id
889          * sql.leftOuterJoin("test2", {id : "id"});
890          * //select * from test left outer join test2 using (id, name)
891          * sql.leftOuterJoin("test2", ["id", "name"]);
892          *
893          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
894          * @param {Array|Object} options When an array is passed in the a using clause is used
895          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
896          *
897          * @return {SQL} this to allow chaining of query elements.
898          */
899         leftOuterJoin: function(tableName, options) {
900             throw new Error("Not Implemented")
901         },
902 
903         /**
904          * Add a full join to another table
905          *
906          * @example
907          * //select * from test full join test2 on test.id=test2.id
908          * sql.fullJoin("test2", {id : "id"});
909          * //select * from test full join test2 using (id, name)
910          * sql.fullJoin("test2", ["id", "name"]);
911          *
912          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
913          * @param {Array|Object} options When an array is passed in the a using clause is used
914          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
915          *
916          * @return {SQL} this to allow chaining of query elements.
917          */
918         fullJoin: function(tableName, options) {
919             throw new Error("Not Implemented")
920         },
921 
922         /**
923          * Add a right join to another table
924          *
925          * @example
926          * //select * from test right join test2 on test.id=test2.id
927          * sql.rightJoin("test2", {id : "id"});
928          * //select * from test right join test2 using (id, name)
929          * sql.rightJoin("test2", ["id", "name"]);
930          *
931          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
932          * @param {Array|Object} options When an array is passed in the a using clause is used
933          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
934          *
935          * @return {SQL} this to allow chaining of query elements.
936          */
937         rightJoin: function(tableName, options) {
938             throw new Error("Not Implemented")
939         },
940 
941         /**
942          * Add a left join to another table
943          *
944          * @example
945          * //select * from test left join test2 on test.id=test2.id
946          * sql.leftJoin("test2", {id : "id"});
947          * //select * from test left join test2 using (id, name)
948          * sql.leftJoin("test2", ["id", "name"]);
949          *
950          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
951          * @param {Array|Object} options When an array is passed in the a using clause is used
952          *          to specify the columns to join on, of an object is passed in then it is the same as using an on clause;
953          *
954          * @return {SQL} this to allow chaining of query elements.
955          */
956         leftJoin: function(tableName, options) {
957             throw new Error("Not Implemented")
958         },
959 
960         /**
961          * Add a natural join to another table
962          *
963          * @example
964          * //select * from test natural full join test2
965          * sql.naturalFullJoin("test2");
966          *
967          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
968          *
969          * @return {SQL} this to allow chaining of query elements.
970          */
971         naturalJoin: function(tableName) {
972             throw new Error("Not Implemented")
973         },
974 
975         /**
976          * Add a natural left join to another table
977          *
978          * @example
979          * //select * from test natural left join test2
980          * sql.naturalLeftJoin("test2");
981          * //select * from test natural join test2
982          * sql.naturalJoin("test2");
983          *
984          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
985          *
986          * @return {SQL} this to allow chaining of query elements.
987          */
988         naturalLeftJoin: function(tableName) {
989             throw new Error("Not Implemented")
990         },
991 
992         /**
993          * Add a natural right join to another table
994          *
995          * @example
996          * //select * from test natural right join test2
997          * sql.naturalRightJoin("test2");
998          *
999          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
1000          *
1001          * @return {SQL} this to allow chaining of query elements.
1002          */
1003         naturalRightJoin: function(tableName) {
1004             throw new Error("Not Implemented")
1005         },
1006         naturalFullJoin: function(tableName) {
1007             throw new Error("Not Implemented")
1008         },
1009 
1010         /**
1011          * Add a cross join to another table
1012          *
1013          * @example
1014          * //select * from test cross join test2
1015          * sql.crossJoin("test2");
1016          *
1017          * @param {String|SQL} table the table or SQL clause that specifies the joining table.
1018          *
1019          * @return {SQL} this to allow chaining of query elements.
1020          */
1021         crossJoin: function(tableName) {
1022             throw new Error("Not Implemented")
1023         },
1024 
1025         /**
1026          * Add an in clause
1027          *
1028          * @example
1029          * //select * from test where id in (1,2,3,4,5)
1030          * sql.in({id : [1,2,3,4,5]});
1031          * sql.find({id : [1,2,3,4,5]});
1032          * //select * from test where id in (1,2,3,4,5) and id2 in (6,7,8,9,10)
1033          * sql.find({id : [1,2,3,4,5], id2 : [6,7,8,9,10]});
1034          * //select * from test where id in (1,2,3,4,5) and id2 not in (6,7,8,9,10)
1035          * sql.in({id : [1,2,3,4,5]}).notIn({id2 : [6,7,8,9,10]});
1036          * //select * from test where id in (1,2,3,4,5) and id2 in (6,7,8,9,10)
1037          * sql.in({id : [1,2,3,4,5], id2 : [6,7,8,9,10]});
1038          * //select * from test where id in (select id2 from test2 where name >= 'A' and name <= 'B')
1039          * sql.in({id : new Mysql("test2", db).select("id2").between({name : ["A", "B"]})});
1040          *
1041          * @param {Object} options key value pairs where the key is coulmn name and the value is an array of values.
1042          *
1043          * @return {SQL} this to allow chaining of query elements.
1044          */
1045         "in": function(options) {
1046             throw new Error("Not Implemented")
1047         },
1048 
1049         /**
1050          * Add a not in clause
1051          *
1052          * @example
1053          * //select * from test where id not in (1,2,3,4,5)
1054          * sql.notIn({id : [1,2,3,4,5]});
1055          * sql.find({id : {notIn : [1,2,3,4,5]}});
1056          * //select * from test where id not in (1,2,3,4,5) and id2 in (6,7,8,9,10)
1057          * sql.notIn({id : [1,2,3,4,5]}).in({id2 : [6,7,8,9,10]});
1058          * //select * from test where id not in (1,2,3,4,5) and id2 not in (6,7,8,9,10)
1059          * sql.notIn({id : [1,2,3,4,5], id2 : [6,7,8,9,10]});
1060          * //select * from test where id not in (select id2 from test2 where name >= 'A' and name <= 'B')
1061          * sql.notIn({id : new Mysql("test2", db).select("id2").between({name : ["A", "B"]})});
1062          * @param {Object} options options key value pairs where the key is coulmn name and the value is an array of values.
1063          *
1064          * @return {SQL} this to allow chaining of query elements.
1065          */
1066         notIn: function(options) {
1067             throw new Error("Not Implemented")
1068         },
1069 
1070         /**
1071          * Add a between check for a column.
1072          *
1073          * @example
1074          * //select * from test where x >= 1 and x <= 5
1075          * sql.between({x : [1,5]});
1076          * //select * from test where x >= 'a' and x <= 'b'
1077          * sql.find({x : {between : ["a","b"]}});
1078          *
1079          * @param options options key value pairs where the
1080          * key is coulmn name and the value is an array of two
1081          * values, first value in the array represents the gte
1082          * value and the second value being the lte value.
1083          *
1084          * @return {SQL} this to allow chaining of query elements.
1085          */
1086         between: function(options) {
1087             throw new Error("Not Implemented")
1088         },
1089 
1090         /**
1091          * Add a not between check for a column.
1092          * @example
1093          * //select * from test where x <= 1 and x >= 5
1094          * sql.notBetween({x : [1,5]});
1095          * //select * from test where x <= 'a' and x >= 'b'
1096          * sql.notBetween({x : ["a","b"]});
1097          * //select * from test where x <= 'a' and x >= 'b'
1098          * sql.find({x : {notBetween : ["a","b"]}});
1099          *
1100          * @param @param options options key value pairs where the
1101          * key is coulmn name and the value is an array of two
1102          * values, first value in the array represents the lte
1103          * value and the second value being the gte value.
1104          *
1105          * @return {SQL} this to allow chaining of query elements.
1106          */
1107         notBetween: function(options) {
1108             throw new Error("Not Implemented")
1109         },
1110 
1111         /**
1112          * Add a count cause to the select portion of the query.
1113          *
1114          * @example
1115          * //select count(name) as name_count from test
1116          * sql.count("name");
1117          * //select count(*) as count from test
1118          * sql.count();
1119 
1120          * @param {String|Array} [options="*"] if a string is supplied
1121          * then a count is added for that particular columns, an array
1122          * adds a count for each column in the array.
1123          *
1124          * @return {SQL} this to allow chaining of query elements.
1125          */
1126         count: function(options) {
1127             throw new Error("Not Implemented")
1128         },
1129 
1130 
1131         /**
1132          * Helper to add a group and count clause.
1133          *
1134          * @example
1135          * //select *, count(name) as name_count from test group by name
1136          * sql.groupAndCount("name");
1137          * @param {String|Array} key specify the columns to group and count on.
1138          * @param {Object} having specify a having clause {@link SQL#having}.
1139          *
1140          * @return {SQL} this to allow chaining of query elements.
1141          */
1142         groupAndCount: function() {
1143             throw new Error("Not Implemented");
1144         },
1145 
1146         /**
1147          * Helper to add a group and sum clause.
1148          *
1149          * @example
1150          * sql.groupAndSum("name");
1151          * //select *, sum(name) as name_sum from test group by name
1152          *
1153          * @param {String|Array} key specify the columns to group and sum on.
1154          * @param {Object} having specify a having clause {@link SQL#having}.
1155          *
1156          * @return {SQL} this to allow chaining of query elements.
1157          */
1158         groupAndSum: function() {
1159             throw new Error("Not Implemented");
1160         },
1161 
1162         /**
1163          * Helper to add a group and avg clause.
1164          *
1165          *  @example
1166          * //select *, avg(name) as name_avg from test group by name
1167          * sql.groupAndAvg("name");
1168          *
1169          * @param {String|Array} key specify the columns to group and avg on.
1170          * @param {Object} having specify a having clause {@link SQL#having}.
1171          *
1172          * @return {SQL} this to allow chaining of query elements.
1173          */
1174         groupAndAvg: function() {
1175             throw new Error("Not Implemented");
1176         },
1177 
1178         /**
1179          * Helper to add a group and min clause.
1180          *
1181          * @example
1182          * //select *, min(name) as name_min from test group by name
1183          * sql.groupAndMin("name");
1184          *
1185          * @param {String|Array} key specify the columns to group and min on.
1186          * @param {Object} having specify a having clause {@link SQL#having}.
1187          *
1188          * @return {SQL} this to allow chaining of query elements.
1189          */
1190         groupAndMin: function() {
1191             throw new Error("Not Implemented");
1192         },
1193 
1194         /**
1195          * Helper to add a group and max clause.
1196          *
1197          * @example
1198          * //select *, max(name) as name_max from test group by name
1199          * sql.groupAndMax("name");
1200          *
1201          * @param {String|Array} key specify the columns to group and max on.
1202          * @param {Object} having specify a having clause {@link SQL#having}.
1203          *
1204          * @return {SQL} this to allow chaining of query elements.
1205          */
1206         groupAndMax: function() {
1207             throw new Error("Not Implemented");
1208         },
1209 
1210         /**
1211          * Helper to add a group and bit and clause.
1212          *
1213          * @example
1214          * //select *, bit_and(name) as name_bit_and from test group by name
1215          * sql.groupAndBitAnd("name");
1216          *
1217          * @param {String|Array} key specify the columns to group and bit and on.
1218          * @param {Object} having specify a having clause {@link SQL#having}.
1219          *
1220          * @return {SQL} this to allow chaining of query elements.
1221          */
1222         groupAndBitAnd: function() {
1223             throw new Error("Not Implemented");
1224         },
1225 
1226         /**
1227          * Helper to add a group and bit or clause.
1228          *
1229          * @example
1230          * //select *, bit_or(name) as name_bit_or from test group by name
1231          * sql.groupAndBitOr("name");
1232          *
1233          * @param {String|Array} key specify the columns to group and bit or on.
1234          * @param {Object} having specify a having clause {@link SQL#having}.
1235          *
1236          * @return {SQL} this to allow chaining of query elements.
1237          */
1238         groupAndBitOr: function() {
1239             throw new Error("Not Implemented");
1240         },
1241 
1242         /**
1243          * Helper to add a group and bit xor clause.
1244          *
1245          * @example
1246          * //select *, bit_xor(name) as name_bit_xor from test group by name
1247          * sql.groupAndBitXor("name");
1248          *
1249          * @param {String|Array} key specify the columns to group and bit xor on.
1250          * @param {Object} having specify a having clause {@link SQL#having}.
1251          *
1252          * @return {SQL} this to allow chaining of query elements.
1253          */
1254         groupAndBitXor: function() {
1255             throw new Error("Not Implemented");
1256         },
1257 
1258         /**
1259          * Helper to add a group and std clause.
1260          *
1261          * @example
1262          * //select *, std(name) as name_std from test group by name
1263          * sql.groupAndStd("name");
1264          *
1265          * @param {String|Array} key specify the columns to group and std on.
1266          * @param {Object} having specify a having clause {@link SQL#having}.
1267          *
1268          * @return {SQL} this to allow chaining of query elements.
1269          */
1270         groupAndStd: function() {
1271             throw new Error("Not Implemented");
1272         },
1273 
1274         /**
1275          * Helper to add a group and std dev pop clause.
1276          *
1277          * @example
1278          * //select *, stddev_pop(name) as name_stddev_pop from test group by name
1279          * sql.groupAndStdDevPop("name");
1280          *
1281          * @param {String|Array} key specify the columns to group and std dev pop on.
1282          * @param {Object} having specify a having clause {@link SQL#having}.
1283          *
1284          * @return {SQL} this to allow chaining of query elements.
1285          */
1286         groupAndStdDevPop: function() {
1287             throw new Error("Not Implemented");
1288         },
1289 
1290         /**
1291          * Helper to add a group and std dev samp clause.
1292          *
1293          * @example
1294          * //select *, stddev_samp(name) as name_stddev_samp from test group by name
1295          * sql.groupAndStdDevSamp("name");
1296          *
1297          * @param {String|Array} key specify the columns to group and std dev samp on.
1298          * @param {Object} having specify a having clause {@link SQL#having}.
1299          *
1300          * @return {SQL} this to allow chaining of query elements.
1301          */
1302         groupAndStdDevSamp: function() {
1303             throw new Error("Not Implemented");
1304         },
1305 
1306         /**
1307          * Helper to add a group and std dev clause.
1308          *
1309          * @example
1310          * //select *, stddev(name) as name_stddev from test group by name
1311          * sql.groupAndStdDev("name");
1312          *
1313          * @param {String|Array} key specify the columns to group and std dev on.
1314          * @param {Object} having specify a having clause {@link SQL#having}.
1315          *
1316          * @return {SQL} this to allow chaining of query elements.
1317          */
1318         groupAndStdDev: function() {
1319             throw new Error("Not Implemented");
1320         },
1321 
1322         /**
1323          * Helper to add a group and var pop clause.
1324          *
1325          * @example
1326          * //select *, var_pop(name) as name_var_pop from test group by name
1327          * sql.groupAndVarPop("name");
1328          *
1329          * @param {String|Array} key specify the columns to group and var pop on.
1330          * @param {Object} having specify a having clause {@link SQL#having}.
1331          *
1332          * @return {SQL} this to allow chaining of query elements.
1333          */
1334         groupAndVarPop: function() {
1335             throw new Error("Not Implemented");
1336         },
1337 
1338         /**
1339          * Helper to add a group and var samp clause.
1340          *
1341          * @example
1342          * //select *, var_samp(name) as name_var_samp from test group by name
1343          * sql.groupAndVarSamp("name");
1344          *
1345          * @param {String|Array} key specify the columns to group and var samp on.
1346          * @param {Object} having specify a having clause {@link SQL#having}.
1347          *
1348          * @return {SQL} this to allow chaining of query elements.
1349          */
1350         groupAndVarSamp: function() {
1351             throw new Error("Not Implemented");
1352         },
1353 
1354         /**
1355          * Helper to add a group and variance clause.
1356          *
1357          * @example
1358          * //select *, variance(name) as name_variance from test group by name
1359          * sql.groupAndVariance("name");
1360          *
1361          * @param {String|Array} key specify the columns to group and variance on.
1362          * @param {Object} having specify a having clause {@link SQL#having}.
1363          *
1364          * @return {SQL} this to allow chaining of query elements.
1365          */
1366         groupAndVariance: function() {
1367             throw new Error("Not Implemented");
1368         },
1369 
1370         /**
1371          * Helper to add a sum clause.
1372          *
1373          * @example
1374          * //select sum(name) as name_sum from test
1375          * sql.sum("name");
1376          *
1377          * @param {String|Array} [options="*"] if a string is supplied
1378          * then a sum is added for that particular columns, an array
1379          * adds a sum for each column in the array.
1380          *
1381          * @return {SQL} this to allow chaining of query elements.
1382          */
1383         sum: function(options) {
1384             throw new Error("Not Implemented")
1385         },
1386 
1387         /**
1388          * @example
1389          * //select avg(name) as name_avg from test
1390          * sql.avg("name");
1391          * @param {String|Array} [options="*"] if a string is supplied
1392          * then a avg is added for that particular columns, an array
1393          * adds a avg for each column in the array.
1394          *
1395          * @return {SQL} this to allow chaining of query elements.
1396          */
1397         avg: function(options) {
1398             throw new Error("Not Implemented")
1399         },
1400 
1401         /**
1402          * Helper to add a min clause.
1403          *
1404          * @example
1405          * //select min(name) as name_min from test
1406          * sql.min("name");
1407          * @param {String|Array} [options="*"] if a string is supplied
1408          * then a min is added for that particular columns, an array
1409          * adds a min for each column in the array.
1410          *
1411          * @return {SQL} this to allow chaining of query elements.
1412          */
1413         min: function(options) {
1414             throw new Error("Not Implemented")
1415         },
1416 
1417         /**
1418          * Helper to add a max clause.
1419          *
1420          * @example
1421          * //select max(name) as name_max from test
1422          * sql.max("name");
1423          * @param {String|Array} [options="*"] if a string is supplied
1424          * then a max is added for that particular columns, an array
1425          * adds a max for each column in the array.
1426          *
1427          * @return {SQL} this to allow chaining of query elements.
1428          */
1429         max: function(options) {
1430             throw new Error("Not Implemented")
1431         },
1432 
1433         /**
1434          * Helper to add a bit and clause.
1435          *
1436          * @example
1437          * //select bit_and(name) as name_bit_and from test
1438          * sql.bitAnd("name");
1439          * @param {String|Array} [options="*"] if a string is supplied
1440          * then a bit and is added for that particular columns, an array
1441          * adds a bit and for each column in the array.
1442          *
1443          * @return {SQL} this to allow chaining of query elements.
1444          */
1445         bitAnd: function(options) {
1446             throw new Error("Not Implemented")
1447         },
1448 
1449         /**
1450          * @example
1451          * //select bit_or(name) as name_bit_or from test
1452          * sql.bitOr("name");
1453          * @param {String|Array} [options="*"] if a string is supplied
1454          * then a bit or is added for that particular columns, an array
1455          * adds a count for each column in the array.
1456          *
1457          * @return {SQL} this to allow chaining of query elements.
1458          */
1459         bitOr: function(options) {
1460             throw new Error("Not Implemented")
1461         },
1462 
1463         /**
1464          * Helper to add a bit xor clause.
1465          *
1466          * @example
1467          * //select bit_xor(name) as name_bit_xor from test
1468          * sql.bitXor("name");
1469          * @param {String|Array} [options="*"] if a string is supplied
1470          * then a bit xor is added for that particular columns, an array
1471          * adds a bit xor for each column in the array.
1472          *
1473          * @return {SQL} this to allow chaining of query elements.
1474          */
1475         bitXor: function(options) {
1476             throw new Error("Not Implemented")
1477         },
1478 
1479         /**
1480          * Helper to add a std clause.
1481          *
1482          * @example
1483          * //select std(name) as name_std from test
1484          * sql.std("name");
1485          * @param {String|Array} [options="*"] if a string is supplied
1486          * then a std is added for that particular columns, an array
1487          * adds a std for each column in the array.
1488          *
1489          * @return {SQL} this to allow chaining of query elements.
1490          */
1491         std: function(options) {
1492             throw new Error("Not Implemented")
1493         },
1494 
1495         /**
1496          * Helper to add a std dev clause.
1497          *
1498          * @example
1499          * //select stddev_pop(name) as name_stddev_pop from test
1500          * sql.stdDevPop("name");
1501          * @param {String|Array} [options="*"] if a string is supplied
1502          * then a std dev pop is added for that particular columns, an array
1503          * adds a std dev pop for each column in the array.
1504          *
1505          * @return {SQL} this to allow chaining of query elements.
1506          */
1507         stdDevPop: function(options) {
1508             throw new Error("Not Implemented")
1509         },
1510 
1511         /**
1512          * Helper to add a std dev samp clause.
1513          *
1514          * @example
1515          * //select stddev_samp(name) as name_stddev_samp from test
1516          * sql.stdDevSamp("name");
1517          * @param {String|Array} [options="*"] if a string is supplied
1518          * then a std dev samp is added for that particular columns, an array
1519          * adds a std dev samp for each column in the array.
1520          *
1521          * @return {SQL} this to allow chaining of query elements.
1522          */
1523         stdDevSamp: function(options) {
1524             throw new Error("Not Implemented")
1525         },
1526 
1527         /**
1528          * Helper to add a std dev clause.
1529          *
1530          * @example
1531          * //select stddev(name) as name_stddev from test
1532          * sql.stdDev("name");
1533          * @param {String|Array} [options="*"] if a string is supplied
1534          * then a std dev is added for that particular columns, an array
1535          * adds a std dev for each column in the array.
1536          *
1537          * @return {SQL} this to allow chaining of query elements.
1538          */
1539         stdDev: function(options) {
1540             throw new Error("Not Implemented")
1541         },
1542 
1543         /**
1544          * Helper to add a var pop clause.
1545          *
1546          * @example
1547          * //select var_pop(name) as name_var_pop from test
1548          * sql.varPop("name");
1549          * @param {String|Array} [options="*"] if a string is supplied
1550          * then a var pop is added for that particular columns, an array
1551          * adds a var pop for each column in the array.
1552          *
1553          * @return {SQL} this to allow chaining of query elements.
1554          */
1555         varPop: function(options) {
1556             throw new Error("Not Implemented")
1557         },
1558 
1559         /**
1560          * Helper to add a var samp clause.
1561          *
1562          * @example
1563          * //select var_samp(name) as name_var_samp from test
1564          * sql.varSamp("name");
1565          * @param options
1566          *
1567          * @param {String|Array} [options="*"] if a string is supplied
1568          * then a var samp is added for that particular columns, an array
1569          * adds a var samp for each column in the array.
1570          *
1571          * @return {SQL} this to allow chaining of query elements.
1572          */
1573         varSamp: function(options) {
1574             throw new Error("Not Implemented")
1575         },
1576 
1577         /**
1578          * Helper to add a variance clause.
1579          *
1580          * @example
1581          * //select variance(name) as name_variance from test
1582          * sql.variance("name");
1583          * @param {String|Array} [options="*"] if a string is supplied
1584          * then a variance is added for that particular columns, an array
1585          * adds a variance for each column in the array.
1586          *
1587          * @return {SQL} this to allow chaining of query elements.
1588          */
1589         variance: function(options) {
1590             throw new Error("Not Implemented")
1591         },
1592 
1593         /**
1594          * Add a like clause.
1595          *
1596          * @example
1597          * //select * from test where name like 'bob'
1598          * sql.like({name : "bob"});
1599          * //select * from test where firstName like 'bob' and lastName not like 'henry'
1600          * sql.find({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
1601          *
1602          * @param {Object} options key, value pairs with the key representing a column,
1603          * and the key represents the like condition.
1604          *
1605          * @return {SQL} this to allow chaining of query elements.
1606          */
1607         like: function(options) {
1608             throw new Error("Not Implemented")
1609         },
1610 
1611         /**
1612          *  Add a not like clause.
1613          *
1614          * @example
1615          * //select * from test where name not like 'bob'
1616          * sql.notLike({name : "bob"});
1617          * //select * from test where firstName like 'bob' and lastName not like 'henry'
1618          * sql.find({firstName : {like : 'bob'}, lastName : {notLike : "henry"}});
1619          *
1620          * @param {Object} options key, value pairs with the key representing a column,
1621          * and the key represents the not like condition.
1622          *
1623          * @return {SQL} this to allow chaining of query elements.
1624          */
1625         notLike: function(options) {
1626             throw new Error("Not Implemented")
1627         },
1628 
1629 
1630         /**
1631          * Performs clean up to add any needed protions of a query if not provided.
1632          *
1633          * @return {SQL} this to allow chaining of query elements.
1634          */
1635         end : function() {
1636             throw new Error("Not Implemented!");
1637         },
1638 
1639         /**
1640          * Executes the query, when finished the promise callback is called
1641          * if the query errors then the promise error is called.
1642          *
1643          * @return {comb.Promise} called back with results or the error call back is called with an error.
1644          */
1645         exec : function() {
1646             this.end();
1647             return this.db.query(this.sql);
1648         },
1649 
1650         /**
1651          * Close the connection.
1652          */
1653         close : function() {
1654             this.db.close();
1655         },
1656 
1657         getters : {
1658             sql : function() {
1659                 return createSQLFromSplit(this.sqlObject);
1660             }
1661         }
1662     },
1663 
1664     static : {
1665         /**@lends SQL*/
1666 
1667         /**
1668          * Create a table.
1669          *
1670          * @param {moose.Table} table the table to create on the database
1671          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1672          *
1673          * @return {comb.Promise} called back with results or the error call back is called with an error.
1674          */
1675         createTable : function(table, db) {
1676             var promise = new Promise();
1677             db.query(table.createTableSql).then(hitch(promise, "callback", true), hitch(promise, "errback"));
1678             return promise;
1679         },
1680 
1681         /**
1682          * Alter a table.
1683          *
1684          * @param {moose.Table} table the table to alter on the database
1685          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1686          *
1687          * @return {comb.Promise} called back with results or the error call back is called with an error.
1688          */
1689         alterTable : function(table, db) {
1690             throw new Error("Not Implemented!");
1691         },
1692 
1693         /**
1694          * Drop a table.
1695          *
1696          * @param {moose.Table} table the table to drop on the database
1697          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1698          *
1699          * @return {comb.Promise} called back with results or the error call back is called with an error.
1700          */
1701         dropTable : function(table, db) {
1702             throw new Error("Not Implemented!");
1703         },
1704 
1705         /**
1706          * Perform a batch insert into a table the objects.
1707          *
1708          * @param {String} table the name of the table
1709          * @param {Object} object the values to insert into the table
1710          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1711          *
1712          * @return {comb.Promise} called back with results or the error call back is called with an error.
1713          */
1714         save : function(table, object, db) {
1715             throw new Error("Not Implemented!");
1716         },
1717 
1718         /**
1719          * Retrieve and create a {@link moose.Table} from a schema stored in the database.
1720          *
1721          * @param {String} tableName name of the table
1722          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1723          *
1724          * @return {comb.Promise} called back with {@link moose.Table} or the error call back is called with an error.
1725          */
1726         schema : function(tableName, db) {
1727             throw new Error("Not Implemented!");
1728         },
1729 
1730         /**
1731          * Retrieve the last inserted id on a database.
1732          *
1733          * @param {moose.adapters.client.Query|moose.adapters.client.TransactionQuery} db the conneciton to the database.
1734          *
1735          * @return {comb.Promise} called back with id or the error call back is called with an error.
1736          */
1737         getLastInsertId : function(db) {
1738             throw new Error("Not Implemented!");
1739         },
1740 
1741         /**
1742          * Create a foreign key statement
1743          * <p><b>See your client adpater for parameters!</b></p>
1744          */
1745         foreignKey : function() {
1746             throw new Error("Not Implemented!");
1747         },
1748 
1749         /**
1750          * Create a add foreign key statement
1751          * <p><b>See your client adpater for parameters!</b></p>
1752          */
1753         addForeignKey :function() {
1754             throw new Error("Not Implemented!");
1755         },
1756 
1757         /**
1758          * Create a drop foreign key statement
1759          * <p><b>See your client adpater for parameters!</b></p>
1760          */
1761         dropForeignKey : function() {
1762             throw new Error("Not Implemented!");
1763         },
1764 
1765         /**
1766          * Create a primary key statement
1767          * <p><b>See your client adpater for parameters!</b></p>
1768          */
1769         primaryKey : function() {
1770             throw new Error("Not Implemented!");
1771         },
1772 
1773         /**
1774          * Create a add primary key statement
1775          * <p><b>See your client adpater for parameters!</b></p>
1776          */
1777         addPrimaryKey : function() {
1778             throw new Error("Not Implemented!");
1779         },
1780 
1781         /**
1782          * Create a drop primary key statement
1783          * <p><b>See your client adpater for parameters!</b></p>
1784          */
1785         dropPrimaryKey : function() {
1786             throw new Error("Not Implemented!");
1787         },
1788 
1789         /**
1790          * Create a unique constraint statement
1791          * <p><b>See your client adpater for parameters!</b></p>
1792          */
1793         unique : function() {
1794             throw new Error("Not Implemented!");
1795         },
1796 
1797         /**
1798          * Create a add unique constraint statement
1799          * <p><b>See your client adpater for parameters!</b></p>
1800          */
1801         addUnique : function() {
1802             throw new Error("Not Implemented!");
1803         },
1804 
1805         /**
1806          * Create a drop unique constraint statement
1807          * <p><b>See your client adpater for parameters!</b></p>
1808          */
1809         dropUnique : function() {
1810             throw new Error("Not Implemented!");
1811         },
1812 
1813         /**
1814          * Create a drop column statement
1815          * <p><b>See your client adpater for parameters!</b></p>
1816          */
1817         dropColumn : function() {
1818             throw new Error("Not Implemented!");
1819         },
1820 
1821         /**
1822          * Create an alter column statement
1823          * <p><b>See your client adpater for parameters!</b></p>
1824          */
1825         alterColumn : function() {
1826             throw new Error("Not Implemented!");
1827         },
1828 
1829         /**
1830          * Create a column statement
1831          * <p><b>See your client adpater for parameters!</b></p>
1832          */
1833         column : function() {
1834             throw new Error("Not Implemented!");
1835         },
1836 
1837         /**
1838          * Create an add column statement
1839          * <p><b>See your client adpater for parameters!</b></p>
1840          */
1841         addColumn : function() {
1842             throw new Error("Not Implemented!");
1843         },
1844 
1845         /**
1846          * Check if a type is a valid type for this adapter.
1847          * @return {Boolean} true if it is a valid type, false otherwise.
1848          */
1849         isValidType : function() {
1850             throw new Error("Not Implemented!");
1851         },
1852         client : null,
1853         types : null,
1854 
1855         /**
1856          * Formats and escapes query string.
1857          * @function
1858          * @param {String} sql the sql to format
1859          * @param {Array} array of values to place in the query.
1860          *
1861          * @return {String} the formatted string.
1862          */
1863         format : format
1864 
1865     }
1866 });
1867 
1868 
1869