Compare commits
	
		
			No commits in common. "master" and "v1.1.0" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										385
									
								
								lib/dbwrap.js
									
									
									
									
									
								
							
							
						
						
									
										385
									
								
								lib/dbwrap.js
									
									
									
									
									
								
							| @ -1,52 +1,9 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| /*global Promise*/ |  | ||||||
| var PromiseA = Promise; |  | ||||||
| 
 |  | ||||||
| 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, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| function wrap(db, dir, dbsMap) { | function wrap(db, dir, dbsMap) { | ||||||
|   // TODO if I put a failure right here,
 |   // TODO if I put a failure right here,
 | ||||||
|   // why doesn't the unhandled promise rejection fire?
 |   // why doesn't the unhandled promise rejection fire?
 | ||||||
|  |   var PromiseA = require('bluebird'); | ||||||
|   var promises = []; |   var promises = []; | ||||||
|   var earr = []; |   var earr = []; | ||||||
|   var debug = false; |   var debug = false; | ||||||
| @ -55,6 +12,34 @@ function wrap(db, dir, dbsMap) { | |||||||
|     dbsMap = {}; |     dbsMap = {}; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   function lowerFirst(str) { | ||||||
|  |     return str.charAt(0).toLowerCase() + str.slice(1); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function snakeCase(str) { | ||||||
|  |     return lowerFirst(str).replace( | ||||||
|  |       /([A-Z])/g | ||||||
|  |     , function ($1) { | ||||||
|  |         return "_" + $1.toLowerCase(); | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function camelCase(str) { | ||||||
|  |     str = str.replace( | ||||||
|  |       /_([a-z])/g | ||||||
|  |     , function (g) { | ||||||
|  |         return g[1].toUpperCase(); | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |     return str; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function upperCamelCase(str) { | ||||||
|  |     // TODO handle UTF-8 properly (use codePointAt, don't use slice)
 | ||||||
|  |     return str.charAt(0).toUpperCase() + camelCase(str).slice(1); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   // PRAGMA schema.table_info(table-name);
 |   // PRAGMA schema.table_info(table-name);
 | ||||||
|   //
 |   //
 | ||||||
|   function sqlite3GetColumns(tablename, columns, cb) { |   function sqlite3GetColumns(tablename, columns, cb) { | ||||||
| @ -162,10 +147,14 @@ function wrap(db, dir, dbsMap) { | |||||||
| 
 | 
 | ||||||
|     dir.indices.forEach(normalizeColumn); |     dir.indices.forEach(normalizeColumn); | ||||||
|     DB._indices = dir.indices; |     DB._indices = dir.indices; | ||||||
|     DB._indicesMap = {}; | 
 | ||||||
|     DB._indices.forEach(function (col) { |     function simpleParse(row) { | ||||||
|       DB._indicesMap[col.name] = col; |       if (!row) { | ||||||
|     }); |         return null; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return simpleMap([row])[0] || null; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     function simpleMap(rows) { |     function simpleMap(rows) { | ||||||
|       if (!rows) { |       if (!rows) { | ||||||
| @ -180,10 +169,10 @@ function wrap(db, dir, dbsMap) { | |||||||
| 
 | 
 | ||||||
|         if (row.json) { |         if (row.json) { | ||||||
|           obj = JSON.parse(row.json); |           obj = JSON.parse(row.json); | ||||||
|  |           delete row.json; | ||||||
|         } else { |         } else { | ||||||
|           obj = {}; |           obj = {}; | ||||||
|         } |         } | ||||||
|         delete row.json; |  | ||||||
| 
 | 
 | ||||||
|         obj[idnameCased] = row[idname]; |         obj[idnameCased] = row[idname]; | ||||||
|         delete row[idname]; |         delete row[idname]; | ||||||
| @ -209,93 +198,6 @@ function wrap(db, dir, dbsMap) { | |||||||
|       return results; |       return results; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     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; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     DB.migrate = function (columns) { |     DB.migrate = function (columns) { | ||||||
|       columns.forEach(normalizeColumn); |       columns.forEach(normalizeColumn); | ||||||
| 
 | 
 | ||||||
| @ -327,129 +229,34 @@ function wrap(db, dir, dbsMap) { | |||||||
|         return PromiseA.reject(err); |         return PromiseA.reject(err); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       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')); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (obj && keys.length) { |       if (obj && keys.length) { | ||||||
|         var conditions = keys.map(function (key) { |         sql += 'WHERE '; | ||||||
|           var dbKey = db.escape(snakeCase(key)); |  | ||||||
|           var value = obj[key]; |  | ||||||
|           if (null === value) { |  | ||||||
|             return dbKey + ' IS NULL'; |  | ||||||
|           } |  | ||||||
| 
 | 
 | ||||||
|           var split, cmd; |         keys.forEach(function (key, i) { | ||||||
|           if (typeof value === 'string') { |           if (i !== 0) { | ||||||
|             value = value.trim(); |             sql += 'AND '; | ||||||
|             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'); |  | ||||||
|             } |  | ||||||
|           } |           } | ||||||
|           if (typeof value === 'object') { |           if (null === obj[key]) { | ||||||
|             cmd = value.condition || value.relation || value.cmd; |             sql += db.escape(snakeCase(key)) + " IS null"; | ||||||
|             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(); |  | ||||||
|             } |  | ||||||
|           } |           } | ||||||
| 
 |           else { | ||||||
|           if (!cmd) { |             // TODO check that key is some type? ignore undefined?
 | ||||||
|             cmd = '='; |             sql += db.escape(snakeCase(key)) + " = '" + db.escape(obj[key]) + "'"; | ||||||
|           } |           } | ||||||
|           // 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; |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|           return dbKey + ' ' + cmd + " '" + db.escape(value) + "'"; |  | ||||||
|         }); |         }); | ||||||
|         if (err) { |  | ||||||
|           return PromiseA.reject(err); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         sql += 'WHERE ' + conditions.join(' AND '); |  | ||||||
|       } |       } | ||||||
|       else if (null !== obj || !(params && params.limit)) { |       else if (null !== obj || (params && !params.limit)) { | ||||||
|         return PromiseA.reject(new Error("to find all you must explicitly specify find(null, { limit: <<int>> })")); |         return PromiseA.reject(new Error("to find all you must explicitly specify find(null, { limit: <<int>> })")); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (params) { |       if (params) { | ||||||
|         if (typeof params.orderByDesc === 'string' && !params.orderBy) { |  | ||||||
|           params.orderBy = params.orderByDesc; |  | ||||||
|           params.orderByDesc = true; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // IMPORTANT: " is not the same to sqlite as '.
 |  | ||||||
|         // // " is exact and necessary
 |  | ||||||
|         if (params.orderBy) { |         if (params.orderBy) { | ||||||
|           sql += " ORDER BY \"" + db.escape(snakeCase(params.orderBy)) + "\" "; |           sql += " ORDER BY \"" + db.escape(snakeCase(params.orderBy) + "\" "); | ||||||
|           if (params.orderByDesc) { |           if (params.orderByDesc) { | ||||||
|             sql += "DESC "; |             sql += 'DESC '; | ||||||
|           } |           } | ||||||
|         } else if (DB._indicesMap.updated_at) { |  | ||||||
|           sql += " ORDER BY \"updated_at\" DESC "; |  | ||||||
|         } else if (DB._indicesMap.created_at) { |  | ||||||
|           sql += " ORDER BY \"created_at\" DESC "; |  | ||||||
|         } |         } | ||||||
|         if (isFinite(params.limit)) { |         if (params.limit) { | ||||||
|           sql += " LIMIT " + parseInt(params.limit, 10); |           sql += " LIMIT " + parseInt(params.limit, 10); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -494,13 +301,8 @@ function wrap(db, dir, dbsMap) { | |||||||
|     DB.save = function (data, oldId) { |     DB.save = function (data, oldId) { | ||||||
|       if (!data[idnameCased] && !oldId) { |       if (!data[idnameCased] && !oldId) { | ||||||
|         // NOTE saving the id both in the object and the id for now
 |         // NOTE saving the id both in the object and the id for now
 | ||||||
|         data[idnameCased] = require('crypto').randomBytes(16).toString('hex').split(''); |         var UUID = require('node-uuid'); | ||||||
|         data[idnameCased].splice(8, 0, '-'); |         data[idnameCased] = UUID.v4(); | ||||||
|         data[idnameCased].splice(8 + 1 + 4, 0, '-'); |  | ||||||
|         data[idnameCased].splice(8 + 1 + 4 + 1 + 4, 0, '-'); |  | ||||||
|         data[idnameCased].splice(8 + 1 + 4 + 1 + 4 + 1 + 4, 0, '-'); |  | ||||||
|         data[idnameCased][14] = 4; // TODO look at the mock uuid in the Go code I wrote
 |  | ||||||
|         data[idnameCased] = data[idnameCased].join(''); |  | ||||||
|         return DB.create(data[idnameCased], data).then(function (/*stats*/) { |         return DB.create(data[idnameCased], data).then(function (/*stats*/) { | ||||||
|           //data._rowid = stats.id;
 |           //data._rowid = stats.id;
 | ||||||
|           return data; |           return data; | ||||||
| @ -571,6 +373,80 @@ function wrap(db, dir, dbsMap) { | |||||||
|       }); |       }); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     // pull indices from object
 | ||||||
|  |     function strainUpdate(id, data/*, vals*/, cb, oldId) { | ||||||
|  |       var fieldable = []; | ||||||
|  |       var json; | ||||||
|  |       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) { | ||||||
|  |         var val = 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) { | ||||||
|  |         json = JSON.stringify(data); | ||||||
|  |         fieldable.push("json"); | ||||||
|  |         //fieldable.push("json = '" + db.escape(json) + "'");
 | ||||||
|  |         vals.push(json); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       vals.push(id); | ||||||
|  | 
 | ||||||
|  |       sql = cb(fieldable); | ||||||
|  | 
 | ||||||
|  |       if (debug) { | ||||||
|  |         console.log('[masterquest-sqlite3] dbwrap.js'); | ||||||
|  |         console.log(sql); | ||||||
|  |         console.log(vals); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       while (vals.length) { | ||||||
|  |         sql = sql.replace(/\?/, "'" + db.escape(vals.shift()) + "'"); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return sql; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     DB.set = function (id, obj, oldId) { |     DB.set = function (id, obj, oldId) { | ||||||
|       obj.updatedAt = Date.now(); |       obj.updatedAt = Date.now(); | ||||||
| 
 | 
 | ||||||
| @ -683,14 +559,9 @@ function wrap(db, dir, dbsMap) { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function promisify(key) { |  | ||||||
|     if ('function' !== typeof db[key] || /Async$/.test(key) || db[key + 'Async']) { return; } |  | ||||||
|     db[key + 'Async'] = require('util').promisify(db[key]); |  | ||||||
|   } |  | ||||||
|   if (!db.__masterquest_init) { |   if (!db.__masterquest_init) { | ||||||
|     db.__masterquest_init = true; |     db.__masterquest_init = true; | ||||||
|     Object.keys(db).forEach(promisify); |     db = PromiseA.promisifyAll(db); | ||||||
|     ['run', 'all'].forEach(promisify); |  | ||||||
|     db.__masterquest_init = true; |     db.__masterquest_init = true; | ||||||
|     db.escape = function (str) { |     db.escape = function (str) { | ||||||
|       // TODO? literals for true,false,null
 |       // TODO? literals for true,false,null
 | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,5 +0,0 @@ | |||||||
| { |  | ||||||
|   "name": "masterquest-sqlite3", |  | ||||||
|   "version": "1.3.0", |  | ||||||
|   "lockfileVersion": 1 |  | ||||||
| } |  | ||||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "masterquest-sqlite3", |   "name": "masterquest-sqlite3", | ||||||
|   "version": "1.3.1", |   "version": "1.1.0", | ||||||
|   "description": "A NoSQL / SQLite3 Hybrid. All your indices are belong to us. Master Quest.", |   "description": "A NoSQL / SQLite3 Hybrid. All your indices are belong to us. Master Quest.", | ||||||
|   "main": "lib/dbwrap", |   "main": "lib/dbwrap", | ||||||
|   "scripts": { |   "scripts": { | ||||||
| @ -8,10 +8,12 @@ | |||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
|     "url": "https://git.coolaj86.com:coolaj86/masterquest-sqlite3.js" |     "url": "git@github.com:coolaj86/node-masterquest-sqlite3.git" | ||||||
|   }, |   }, | ||||||
|   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", | ||||||
|   "license": "(MIT OR Apache-2.0)", |   "license": "(MIT OR Apache-2.0)", | ||||||
|   "homepage": "https://git.coolaj86.com:coolaj86/masterquest-sqlite3.js", |   "homepage": "https://github.com/coolaj86/masterquest-sqlite3", | ||||||
|   "dependencies": {} |   "dependencies": { | ||||||
|  |     "bluebird": "^3.0.5" | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user