| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  | function lowerFirst(str) { | 
					
						
							|  |  |  |   return str.charAt(0).toLowerCase() + str.substr(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function snakeCase(str) { | 
					
						
							|  |  |  |   return lowerFirst(str).replace(/([A-Z])/g, function (match) { | 
					
						
							|  |  |  |     return "_" + match.toLowerCase(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function camelCase(str) { | 
					
						
							|  |  |  |   return str.replace(/_([a-z])/g, function (match) { | 
					
						
							|  |  |  |     return match[1].toUpperCase(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function upperCamelCase(str) { | 
					
						
							|  |  |  |   var camel = camelCase(str); | 
					
						
							|  |  |  |   return camel.charAt(0).toUpperCase() + camel.substr(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var searchConditions = { | 
					
						
							|  |  |  |   '=':  true, | 
					
						
							|  |  |  |   '==': true, | 
					
						
							|  |  |  |   '!=': true, | 
					
						
							|  |  |  |   '<>': true, | 
					
						
							|  |  |  |   '<':  true, | 
					
						
							|  |  |  |   '<=': true, | 
					
						
							|  |  |  |   '!<': true, | 
					
						
							|  |  |  |   '>':  true, | 
					
						
							|  |  |  |   '>=': true, | 
					
						
							|  |  |  |   '!>': true, | 
					
						
							|  |  |  |   'IS': true, | 
					
						
							|  |  |  |   'IS NOT': true, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   'IN':          true, | 
					
						
							|  |  |  |   'NOT IN':      true, | 
					
						
							|  |  |  |   'LIKE':        true, | 
					
						
							|  |  |  |   'NOT LIKE':    true, | 
					
						
							|  |  |  |   'GLOB':        true, | 
					
						
							|  |  |  |   'NOT GLOB':    true, | 
					
						
							|  |  |  |   'BETWEEN':     true, | 
					
						
							|  |  |  |   'NOT BETWEEN': true, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-03 20:22:16 -05:00
										 |  |  | function wrap(db, dir, dbsMap) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |   // TODO if I put a failure right here,
 | 
					
						
							|  |  |  |   // why doesn't the unhandled promise rejection fire?
 | 
					
						
							|  |  |  |   var PromiseA = require('bluebird'); | 
					
						
							|  |  |  |   var promises = []; | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |   var earr = []; | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |   var debug = false; | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-03 20:22:16 -05:00
										 |  |  |   if (!dbsMap) { | 
					
						
							|  |  |  |     dbsMap = {}; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |   // PRAGMA schema.table_info(table-name);
 | 
					
						
							| 
									
										
										
										
											2016-01-02 21:24:17 -08:00
										 |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |   function sqlite3GetColumns(tablename, columns, cb) { | 
					
						
							|  |  |  |     var sql = "PRAGMA table_info(" + db.escape(tablename) + ")"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     db.all(sql, earr, function (err, result) { | 
					
						
							|  |  |  |       if (err) { | 
					
						
							|  |  |  |         console.error('[Error] query columns'); | 
					
						
							|  |  |  |         console.error(err.stack); | 
					
						
							|  |  |  |         cb(err); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |       if (debug) { | 
					
						
							|  |  |  |         console.log('sqlite3 rows 0'); | 
					
						
							|  |  |  |         console.log(result); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       function alterTable() { | 
					
						
							|  |  |  |         var column = columns.pop(); | 
					
						
							|  |  |  |         var sql; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!column) { | 
					
						
							|  |  |  |           cb(null); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((result.rows||result).some(function (row) { | 
					
						
							|  |  |  |           return (row.column_name || row.name) === snakeCase(column.name); | 
					
						
							|  |  |  |         })) { | 
					
						
							|  |  |  |           alterTable(); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sql = "ALTER TABLE " + db.escape(tablename) | 
					
						
							|  |  |  |           + " ADD COLUMN " | 
					
						
							|  |  |  |           + db.escape(column.name) + " " + db.escape(column.type) | 
					
						
							|  |  |  |           + " DEFAULT null" | 
					
						
							|  |  |  |           ; | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (debug) { | 
					
						
							|  |  |  |           console.log('sqlite3 1'); | 
					
						
							|  |  |  |           console.log(sql); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         db.all(sql, earr, function (err, results) { | 
					
						
							|  |  |  |           if (err) { | 
					
						
							|  |  |  |             console.error("[Error] add column '" + tablename + "'"); | 
					
						
							| 
									
										
										
										
											2017-01-14 17:56:11 -05:00
										 |  |  |             console.error(sql); | 
					
						
							|  |  |  |             console.error(err.stack || new Error('stack').stack); | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |             cb(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |           if (debug) { | 
					
						
							|  |  |  |             console.log('sqlite3 rows 1'); | 
					
						
							|  |  |  |             console.log(results); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           alterTable(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       columns = columns.slice(0); | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |       alterTable(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function normalizeColumn(col, i, arr) { | 
					
						
							|  |  |  |     if ('string' === typeof col) { | 
					
						
							|  |  |  |       col = arr[i] = { name: col, type: 'text' }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!col.type) { | 
					
						
							|  |  |  |       col.type = 'text'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     col.type = col.type.toLowerCase(); // oh postgres...
 | 
					
						
							|  |  |  |     col.name = snakeCase(col.name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return col; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |   function createTable(dir) { | 
					
						
							|  |  |  |     if (!dir.modelname && !dir.tablename) { | 
					
						
							|  |  |  |       throw new Error('Please specify dir.modelname'); | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     if (!dir.tablename) { | 
					
						
							|  |  |  |       dir.tablename = snakeCase(dir.modelname); | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     if (!dir.modelname) { | 
					
						
							|  |  |  |       dir.modelname = upperCamelCase(dir.tablename); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dir.indices) { | 
					
						
							|  |  |  |       dir.indices = []; | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |     var DB = {}; | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     var tablename = (db.escape(dir.tablename || 'data')); | 
					
						
							|  |  |  |     var idname = (db.escape(dir.idname || 'id')); | 
					
						
							|  |  |  |     var idnameCased = (camelCase(dir.idname || 'id')); | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     dir.indices.forEach(normalizeColumn); | 
					
						
							| 
									
										
										
										
											2016-07-12 11:37:08 -04:00
										 |  |  |     DB._indices = dir.indices; | 
					
						
							| 
									
										
										
										
											2018-09-15 14:04:43 -06:00
										 |  |  |     DB._indicesMap = {}; | 
					
						
							|  |  |  |     DB._indices.forEach(function (col) { | 
					
						
							|  |  |  |       DB._indicesMap[col.name] = col; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function simpleMap(rows) { | 
					
						
							|  |  |  |       if (!rows) { | 
					
						
							|  |  |  |         return []; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var results = rows.map(function (row, i) { | 
					
						
							|  |  |  |         // set up for garbage collection
 | 
					
						
							|  |  |  |         rows[i] = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var obj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (row.json) { | 
					
						
							|  |  |  |           obj = JSON.parse(row.json); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           obj = {}; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |         delete row.json; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         obj[idnameCased] = row[idname]; | 
					
						
							| 
									
										
										
										
											2015-10-20 08:47:43 +00:00
										 |  |  |         delete row[idname]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Object.keys(row).forEach(function (fieldname) { | 
					
						
							| 
									
										
										
										
											2016-03-26 17:03:19 -04:00
										 |  |  |           // Ideally it shouldn't be possible to overriding a former proper column,
 | 
					
						
							|  |  |  |           // but when a new indexable field is added, the old value is still in json
 | 
					
						
							|  |  |  |           // TODO one-time upgrade of all rows when a new column is added
 | 
					
						
							|  |  |  |           if (null === row[fieldname] || 'undefined' === typeof row[fieldname] || '' === row[fieldname]) { | 
					
						
							|  |  |  |             obj[camelCase(fieldname)] = row[fieldname] || obj[camelCase(fieldname)] || row[fieldname]; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             obj[camelCase(fieldname)] = row[fieldname]; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-10-20 08:47:43 +00:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return obj; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |       }); | 
					
						
							|  |  |  |       // set up for garbage collection
 | 
					
						
							|  |  |  |       rows.length = 0; | 
					
						
							|  |  |  |       rows = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return results; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |     function simpleParse(row) { | 
					
						
							|  |  |  |       if (!row) { | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return simpleMap([row])[0] || null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // pull indices from object
 | 
					
						
							|  |  |  |     function strainUpdate(id, data/*, vals*/, cb, oldId) { | 
					
						
							|  |  |  |       var fieldable = []; | 
					
						
							|  |  |  |       var sql; | 
					
						
							|  |  |  |       var vals = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ['hasOne', 'hasMany', 'hasAndBelongsToMany', 'belongsTo', 'belongsToMany'].forEach(function (relname) { | 
					
						
							|  |  |  |         var rels = dir[relname]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!rels) { | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!Array.isArray(rels)) { | 
					
						
							|  |  |  |           rels = [rels]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // don't save relationships
 | 
					
						
							|  |  |  |         rels.forEach(function (colname) { | 
					
						
							|  |  |  |           delete data[colname]; | 
					
						
							|  |  |  |           delete data[camelCase(colname)]; | 
					
						
							|  |  |  |           // TODO placehold relationships on find / get?
 | 
					
						
							|  |  |  |           // data[camelCase(colname)] = null;
 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dir.indices.forEach(function (col) { | 
					
						
							|  |  |  |         // We prioritze the raw name rather than the camelCase name because it's not in the object
 | 
					
						
							|  |  |  |         // we give for retrieved entries, so if it's present then the user put it there themselves.
 | 
					
						
							|  |  |  |         var val = data[col.name] || data[camelCase(col.name)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //if (col.name in data)
 | 
					
						
							|  |  |  |         if ('undefined' !== typeof val) { | 
					
						
							|  |  |  |           /* | 
					
						
							|  |  |  |           fieldable.push( | 
					
						
							|  |  |  |             db.escape(snakeCase(col.name)) | 
					
						
							|  |  |  |           + " = '" + db.escape(val) + "'" | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |           */ | 
					
						
							|  |  |  |           fieldable.push(db.escape(snakeCase(col.name))); | 
					
						
							|  |  |  |           vals.push(val); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         delete data[col.name]; | 
					
						
							|  |  |  |         delete data[camelCase(col.name)]; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!oldId) { | 
					
						
							|  |  |  |         delete data[idnameCased]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!fieldable.length || Object.keys(data).length) { | 
					
						
							|  |  |  |         vals.push(JSON.stringify(data)); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         vals.push(null); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       fieldable.push('json'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       vals.push(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sql = cb(fieldable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (debug) { | 
					
						
							|  |  |  |         console.log('[masterquest-sqlite3] dbwrap.js'); | 
					
						
							|  |  |  |         console.log(sql); | 
					
						
							|  |  |  |         console.log(vals); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       vals.forEach(function (val) { | 
					
						
							|  |  |  |         if (null === val || 'number' === typeof val) { | 
					
						
							|  |  |  |           sql = sql.replace('?', String(val)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           sql = sql.replace('?', "'" + db.escape(val) + "'"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return sql; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |     DB.migrate = function (columns) { | 
					
						
							|  |  |  |       columns.forEach(normalizeColumn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |         sqlite3GetColumns(tablename, columns, function (err) { | 
					
						
							|  |  |  |           if (err) { | 
					
						
							|  |  |  |             reject(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           resolve(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     DB.find = function (obj, params) { | 
					
						
							| 
									
										
										
										
											2016-03-23 03:37:20 +00:00
										 |  |  |       var err; | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |       var sql = 'SELECT * FROM \'' + tablename + '\' '; | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |       var keys = obj && Object.keys(obj); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 03:38:59 +00:00
										 |  |  |       if (obj) { | 
					
						
							|  |  |  |         Object.keys(obj).forEach(function (key) { | 
					
						
							|  |  |  |           if (undefined === obj[key]) { | 
					
						
							|  |  |  |             err = new Error("'" + key + "' was `undefined'. For security purposes you must explicitly set the value to null or ''"); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-03-23 03:37:20 +00:00
										 |  |  |       if (err) { | 
					
						
							|  |  |  |         return PromiseA.reject(err); | 
					
						
							| 
									
										
										
										
											2016-03-22 21:43:13 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |       if (params && params.limit) { | 
					
						
							|  |  |  |         params.limit = parseInt(params.limit, 10); | 
					
						
							|  |  |  |         // remember to check for the case of NaN
 | 
					
						
							|  |  |  |         if (!params.limit || params.limit <= 0) { | 
					
						
							|  |  |  |           return PromiseA.reject(new Error('limit must be a positive integer')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |       if (obj && keys.length) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |         var conditions = keys.map(function (key) { | 
					
						
							|  |  |  |           var dbKey = db.escape(snakeCase(key)); | 
					
						
							|  |  |  |           var value = obj[key]; | 
					
						
							|  |  |  |           if (null === value) { | 
					
						
							|  |  |  |             return dbKey + ' IS NULL'; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |           var split, cmd; | 
					
						
							|  |  |  |           if (typeof value === 'string') { | 
					
						
							|  |  |  |             value = value.trim(); | 
					
						
							|  |  |  |             if (['IS NULL', 'IS NOT NULL'].indexOf(value.toUpperCase()) !== -1) { | 
					
						
							|  |  |  |               return dbKey + ' ' + value.toUpperCase(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             split = value.split(' '); | 
					
						
							|  |  |  |             if (searchConditions[split[0].toUpperCase()]) { | 
					
						
							|  |  |  |               cmd = split[0].toUpperCase(); | 
					
						
							|  |  |  |               value = split.slice(1).join(' '); | 
					
						
							|  |  |  |             } else if (searchConditions[split.slice(0, 2).join(' ').toUpperCase()]) { | 
					
						
							|  |  |  |               cmd = split.slice(0, 2).join(' ').toUpperCase(); | 
					
						
							|  |  |  |               value = split.slice(2).join(' '); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // If we were given something like "BEGINS WITH 'something quoted'" we don't want
 | 
					
						
							|  |  |  |             // to include the quotes (we'll quote it again later) so we strip them out here.
 | 
					
						
							|  |  |  |             if (cmd) { | 
					
						
							|  |  |  |               value = value.replace(/^(['"])(.*)\1$/, '$2'); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |           if (typeof value === 'object') { | 
					
						
							|  |  |  |             cmd = value.condition || value.relation || value.cmd; | 
					
						
							|  |  |  |             value = value.value; | 
					
						
							|  |  |  |             if (!cmd || !value) { | 
					
						
							|  |  |  |               err = new Error("'"+key+"' was an object, but missing condition and/or value"); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (typeof cmd !== 'string' || !searchConditions[cmd.toUpperCase()]) { | 
					
						
							|  |  |  |               err = new Error("'"+key+"' tried to use invalid condition '"+cmd+"'"); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               cmd = cmd.toUpperCase(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (!cmd) { | 
					
						
							|  |  |  |             cmd = '='; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           // The IN condition is special in that we can't quote the value as a single value,
 | 
					
						
							|  |  |  |           // so it requires a little more logic to actually work and still be sanitary.
 | 
					
						
							|  |  |  |           if (cmd === 'IN' || cmd === 'NOT IN') { | 
					
						
							|  |  |  |             if (typeof value === 'string') { | 
					
						
							|  |  |  |               value = value.split((params || {}).seperator || /[\s,]+/); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!Array.isArray(value)) { | 
					
						
							|  |  |  |               err = new Error("'"+key+"' has invalid value for use with 'IN'"); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             value = value.map(function (val) { | 
					
						
							|  |  |  |               return "'"+db.escape(val)+"'"; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             return dbKey + ' ' + cmd + ' (' + value.join(',') + ')'; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           // The BETWEEN condition is also special for the same reason as IN
 | 
					
						
							|  |  |  |           if (cmd === 'BETWEEN' || cmd === 'NOT BETWEEN') { | 
					
						
							|  |  |  |             if (typeof value === 'string') { | 
					
						
							|  |  |  |               value = value.split((params || {}).seperator || /[\s,]+(AND\s+)?/i); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!Array.isArray(value) || value.length !== 2) { | 
					
						
							|  |  |  |               err = new Error("'"+key+"' has invalid value for use with 'BETWEEN'"); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             value = value.map(function (val) { | 
					
						
							|  |  |  |               return "'"+db.escape(val)+"'"; | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             return dbKey + ' ' + cmd + ' ' + value.join(' AND '); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           // If we are supposed to compare to another field then make sure the name is correct,
 | 
					
						
							|  |  |  |           // and that we don't try to quote the name.
 | 
					
						
							|  |  |  |           if (typeof value === 'string' && /^[a-zA-Z0-9_]*$/.test(value)) { | 
					
						
							|  |  |  |             var snake = snakeCase(value); | 
					
						
							|  |  |  |             if (dir.indices.some(function (col) { return snake === col.name; })) { | 
					
						
							|  |  |  |               return dbKey + ' ' + cmd + ' ' + snake; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |           return dbKey + ' ' + cmd + " '" + db.escape(value) + "'"; | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |         if (err) { | 
					
						
							|  |  |  |           return PromiseA.reject(err); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sql += 'WHERE ' + conditions.join(' AND '); | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |       else if (null !== obj || !(params && params.limit)) { | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |         return PromiseA.reject(new Error("to find all you must explicitly specify find(null, { limit: <<int>> })")); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |       if (params) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:15:54 -06:00
										 |  |  |         if (typeof params.orderByDesc === 'string' && !params.orderBy) { | 
					
						
							|  |  |  |           params.orderBy = params.orderByDesc; | 
					
						
							|  |  |  |           params.orderByDesc = true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:47:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // IMPORTANT: " is not the same to sqlite as '.
 | 
					
						
							|  |  |  |         // // " is exact and necessary
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         if (params.orderBy) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:47:04 -06:00
										 |  |  |           sql += " ORDER BY \"" + db.escape(snakeCase(params.orderBy)) + "\" "; | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |           if (params.orderByDesc) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:04:43 -06:00
										 |  |  |             sql += "DESC "; | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:04:43 -06:00
										 |  |  |         } else if (DB._indicesMap.updated_at) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:47:04 -06:00
										 |  |  |           sql += " ORDER BY \"updated_at\" DESC "; | 
					
						
							| 
									
										
										
										
											2018-09-15 14:04:43 -06:00
										 |  |  |         } else if (DB._indicesMap.created_at) { | 
					
						
							| 
									
										
										
										
											2018-09-15 14:47:04 -06:00
										 |  |  |           sql += " ORDER BY \"created_at\" DESC "; | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-09-15 14:04:43 -06:00
										 |  |  |         if (isFinite(params.limit)) { | 
					
						
							| 
									
										
										
										
											2015-10-20 08:00:12 +00:00
										 |  |  |           sql += " LIMIT " + parseInt(params.limit, 10); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:51:08 -06:00
										 |  |  |       return db.allAsync(sql, []).then(simpleMap); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DB.get = function (id) { | 
					
						
							|  |  |  |       var sql = "SELECT * FROM " + tablename + " WHERE " + idname + " = ?"; | 
					
						
							|  |  |  |       var values = [id]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return db.getAsync(sql, values).then(function (rows) { | 
					
						
							|  |  |  |         if (Array.isArray(rows)) { | 
					
						
							|  |  |  |           if (!rows.length) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return rows[0] || null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return rows; | 
					
						
							|  |  |  |       }).then(simpleParse); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |     DB.upsert = function (id, data, oldId) { | 
					
						
							| 
									
										
										
										
											2015-11-17 08:29:45 +00:00
										 |  |  |       if (!data) { | 
					
						
							|  |  |  |         data = id; | 
					
						
							|  |  |  |         id = data[idnameCased]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |       return DB.set(oldId || id, data, oldId).then(function (result) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         var success = result.changes >= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (success) { | 
					
						
							|  |  |  |           return result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return DB.create(id, data); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |     DB.save = function (data, oldId) { | 
					
						
							|  |  |  |       if (!data[idnameCased] && !oldId) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         // NOTE saving the id both in the object and the id for now
 | 
					
						
							| 
									
										
										
										
											2018-05-17 03:54:13 -06:00
										 |  |  |         data[idnameCased] = require('uuid').v4(); | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         return DB.create(data[idnameCased], data).then(function (/*stats*/) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |           //data._rowid = stats.id;
 | 
					
						
							|  |  |  |           return data; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |       return DB.set(oldId || data[idnameCased], data, oldId).then(function (result) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         var success = result.changes >= 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (success) { | 
					
						
							|  |  |  |           return result; | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2015-10-05 23:31:07 -07:00
										 |  |  |           //console.log('[debug result of set]', result.sql);
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |           delete result.sql; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return null; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |     DB.create = function (id, obj) { | 
					
						
							|  |  |  |       if (!obj) { | 
					
						
							|  |  |  |         obj = id; | 
					
						
							|  |  |  |         id = obj[idnameCased]; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (!id) { | 
					
						
							|  |  |  |         return PromiseA.reject(new Error("no id supplied")); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-16 14:20:16 -04:00
										 |  |  |       obj.createdAt = Date.now(); | 
					
						
							|  |  |  |       obj.updatedAt = Date.now(); | 
					
						
							| 
									
										
										
										
											2016-03-03 20:22:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |       return new PromiseA(function (resolve, reject) { | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         var json = JSON.stringify(obj); | 
					
						
							|  |  |  |         var data = JSON.parse(json); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |         var sql; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // removes known fields from data
 | 
					
						
							|  |  |  |         sql = strainUpdate(id, data, function sqlTpl(fieldable) { | 
					
						
							|  |  |  |           return "INSERT INTO " + tablename + " (" + fieldable.join(', ') + ", " + idname + ")" | 
					
						
							|  |  |  |             //+ " VALUES ('" + vals.join("', '") + "')"
 | 
					
						
							|  |  |  |             + " VALUES (" + fieldable.map(function () { return '?'; }).join(", ") + ", ?)" | 
					
						
							|  |  |  |             ; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 23:31:07 -07:00
										 |  |  |         //console.log('[debug] DB.create() sql:', sql);
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |         db.run(sql, [], function (err) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |           if (err) { | 
					
						
							|  |  |  |             reject(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // NOTE changes is 1 even if the value of the updated record stays the same
 | 
					
						
							|  |  |  |           // (PostgreSQL would return 0 in that case)
 | 
					
						
							|  |  |  |           // thus if changes is 0 then it failed, otherwise it succeeded
 | 
					
						
							|  |  |  |           /* | 
					
						
							|  |  |  |           console.log('[log db wrapper insert]'); | 
					
						
							|  |  |  |           console.log(this); // sql, lastID, changes
 | 
					
						
							|  |  |  |           console.log(this.sql); | 
					
						
							|  |  |  |           console.log('insert lastID', this.lastID); // sqlite's internal rowId
 | 
					
						
							|  |  |  |           console.log('insert changes', this.changes); | 
					
						
							|  |  |  |           */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           //this.id = id;
 | 
					
						
							|  |  |  |           resolve(this); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |     DB.set = function (id, obj, oldId) { | 
					
						
							| 
									
										
										
										
											2016-03-16 14:20:16 -04:00
										 |  |  |       obj.updatedAt = Date.now(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |       var json = JSON.stringify(obj); | 
					
						
							|  |  |  |       var data = JSON.parse(json); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |       return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |         function sqlTpl(fieldable) { | 
					
						
							|  |  |  |           // this will always at least have one fieldable value: json
 | 
					
						
							|  |  |  |           return "UPDATE " + tablename + " SET " | 
					
						
							|  |  |  |             + (fieldable.join(' = ?, ') + " = ?") | 
					
						
							|  |  |  |             + " WHERE " + idname + " = ?" | 
					
						
							|  |  |  |             ; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |         //var vals = [];
 | 
					
						
							|  |  |  |         // removes known fields from data
 | 
					
						
							| 
									
										
										
										
											2016-03-03 20:22:16 -05:00
										 |  |  |         data.updated_at = Date.now(); | 
					
						
							| 
									
										
										
										
											2017-03-16 20:20:19 -04:00
										 |  |  |         var sql = strainUpdate(id, data/*, vals*/, sqlTpl, oldId); | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 23:31:07 -07:00
										 |  |  |         //console.log('[debug] DB.set() sql:', sql);
 | 
					
						
							| 
									
										
										
										
											2015-09-22 02:08:58 -06:00
										 |  |  |         db.run(sql, /*vals*/[], function (err) { | 
					
						
							| 
									
										
										
										
											2015-10-05 23:31:07 -07:00
										 |  |  |           //console.log('[debug] error:', err);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |           if (err) { | 
					
						
							|  |  |  |             reject(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // it isn't possible to tell if the update succeeded or failed
 | 
					
						
							|  |  |  |           // only if the update resulted in a change or not
 | 
					
						
							|  |  |  |           /* | 
					
						
							|  |  |  |           console.log('[log db wrapper set]'); | 
					
						
							|  |  |  |           console.log(this); // sql, lastID, changes
 | 
					
						
							|  |  |  |           console.log(this.sql); | 
					
						
							|  |  |  |           console.log('update lastID', this.lastID); // always 0 (except on INSERT)
 | 
					
						
							|  |  |  |           console.log('update changes', this.changes); | 
					
						
							|  |  |  |           */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           resolve(this); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DB.destroy = function (id) { | 
					
						
							|  |  |  |       if ('object' === typeof id) { | 
					
						
							| 
									
										
										
										
											2015-09-21 20:14:07 -06:00
										 |  |  |         id = id[idnameCased]; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |         var sql = "DELETE FROM " + tablename + " WHERE " + idname + " = ?"; | 
					
						
							|  |  |  |         var values = [id]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         db.run(sql, values, function (err) { | 
					
						
							|  |  |  |           if (err) { | 
					
						
							|  |  |  |             reject(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // it isn't possible to tell if the update succeeded or failed
 | 
					
						
							|  |  |  |           // only if the update resulted in a change or not
 | 
					
						
							|  |  |  |           /* | 
					
						
							|  |  |  |           console.log('[log db wrapper delete]'); | 
					
						
							|  |  |  |           console.log(this); // sql, lastID, changes
 | 
					
						
							|  |  |  |           console.log(this.sql); | 
					
						
							|  |  |  |           console.log('delete lastID', this.lastID); // always 0 (except on INSERT)
 | 
					
						
							|  |  |  |           console.log('delete changes', this.changes); | 
					
						
							|  |  |  |           */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           resolve(this); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DB._db = db; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |       var indexable = [idname + ' TEXT']; | 
					
						
							|  |  |  |       var sql; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |       dir.indices.forEach(function (col) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |         if ('string' === typeof col) { | 
					
						
							|  |  |  |           col = { name: col, type: 'TEXT' }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!col.type) { | 
					
						
							|  |  |  |           col.type = 'TEXT'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         indexable.push( | 
					
						
							|  |  |  |           db.escape(snakeCase(col.name)) | 
					
						
							|  |  |  |         + ' ' + db.escape(col.type) | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       indexable.push('json TEXT'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sql = "CREATE TABLE IF NOT EXISTS '" + tablename + "' " | 
					
						
							|  |  |  |         + "(" + indexable.join(', ') + ", PRIMARY KEY(" + idname + "))" | 
					
						
							|  |  |  |         ; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |       db.runAsync(sql).then(function () { | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |         sqlite3GetColumns(tablename, dir.indices, function (err) { | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |           if (err) { | 
					
						
							|  |  |  |             console.error('[Error] dbwrap get columns'); | 
					
						
							|  |  |  |             console.error(err.stack); | 
					
						
							|  |  |  |             reject(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |           resolve(DB); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }, reject); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-29 19:38:04 -06:00
										 |  |  |   if (!db.__masterquest_init) { | 
					
						
							|  |  |  |     db.__masterquest_init = true; | 
					
						
							|  |  |  |     db = PromiseA.promisifyAll(db); | 
					
						
							|  |  |  |     db.__masterquest_init = true; | 
					
						
							|  |  |  |     db.escape = function (str) { | 
					
						
							|  |  |  |       // TODO? literals for true,false,null
 | 
					
						
							|  |  |  |       // error on undefined?
 | 
					
						
							|  |  |  |       if (undefined === str) { | 
					
						
							|  |  |  |         str = ''; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return String(str).replace(/'/g, "''"); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dir && dir.verbose || db.verbose) { | 
					
						
							|  |  |  |       console.log('Getting Verbose up in here'); | 
					
						
							|  |  |  |       db.on('trace', function (str) { | 
					
						
							|  |  |  |         console.log('SQL:', str); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       db.on('profile', function (sql, ms) { | 
					
						
							|  |  |  |         console.log('Profile:', ms); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   dbsMap.sql = db; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |   dir.forEach(function (dir) { | 
					
						
							| 
									
										
										
										
											2016-03-03 20:22:16 -05:00
										 |  |  |     // TODO if directive is the same as existing dbsMap, skip it
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |     promises.push(createTable(dir).then(function (dbw) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-09 00:57:31 +00:00
										 |  |  |       dbsMap[dir.modelname] = dbw; | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return dbw; | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-01 04:44:52 +00:00
										 |  |  |   return PromiseA.all(promises).then(function (/*dbs*/) { | 
					
						
							| 
									
										
										
										
											2015-08-27 21:33:46 -06:00
										 |  |  |     return dbsMap; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.wrap = wrap; |