manually merge @tigerbot's updates (operator support and a few other things)
This commit is contained in:
		
							parent
							
								
									c59c0f5e8f
								
							
						
					
					
						commit
						cfd516e24f
					
				
							
								
								
									
										367
									
								
								lib/dbwrap.js
									
									
									
									
									
								
							
							
						
						
									
										367
									
								
								lib/dbwrap.js
									
									
									
									
									
								
							@ -1,5 +1,47 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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?
 | 
				
			||||||
@ -12,34 +54,6 @@ 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) {
 | 
				
			||||||
@ -152,14 +166,6 @@ function wrap(db, dir, dbsMap) {
 | 
				
			|||||||
      DB._indicesMap[col.name] = col;
 | 
					      DB._indicesMap[col.name] = col;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function simpleParse(row) {
 | 
					 | 
				
			||||||
      if (!row) {
 | 
					 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return simpleMap([row])[0] || null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function simpleMap(rows) {
 | 
					    function simpleMap(rows) {
 | 
				
			||||||
      if (!rows) {
 | 
					      if (!rows) {
 | 
				
			||||||
        return [];
 | 
					        return [];
 | 
				
			||||||
@ -173,10 +179,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];
 | 
				
			||||||
@ -202,6 +208,93 @@ 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,36 +326,124 @@ function wrap(db, dir, dbsMap) {
 | 
				
			|||||||
        return PromiseA.reject(err);
 | 
					        return PromiseA.reject(err);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (obj && keys.length) {
 | 
					      if (params && params.limit) {
 | 
				
			||||||
        sql += 'WHERE ';
 | 
					        params.limit = parseInt(params.limit, 10);
 | 
				
			||||||
 | 
					        // remember to check for the case of NaN
 | 
				
			||||||
        keys.forEach(function (key, i) {
 | 
					        if (!params.limit || params.limit <= 0) {
 | 
				
			||||||
          if (i !== 0) {
 | 
					          return PromiseA.reject(new Error('limit must be a positive integer'));
 | 
				
			||||||
            sql += 'AND ';
 | 
					        }
 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          if (null === obj[key]) {
 | 
					 | 
				
			||||||
            sql += db.escape(snakeCase(key)) + " IS null";
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          else {
 | 
					 | 
				
			||||||
            // TODO check that key is some type? ignore undefined?
 | 
					 | 
				
			||||||
            sql += db.escape(snakeCase(key)) + " = '" + db.escape(obj[key]) + "'";
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else if (null !== obj || (params && !params.limit)) {
 | 
					
 | 
				
			||||||
 | 
					      if (obj && keys.length) {
 | 
				
			||||||
 | 
					        var conditions = keys.map(function (key) {
 | 
				
			||||||
 | 
					          var dbKey = db.escape(snakeCase(key));
 | 
				
			||||||
 | 
					          var value = obj[key];
 | 
				
			||||||
 | 
					          if (null === value) {
 | 
				
			||||||
 | 
					            return dbKey + ' IS NULL';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          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');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          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();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          return dbKey + ' ' + cmd + " '" + db.escape(value) + "'";
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					          return PromiseA.reject(err);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sql += 'WHERE ' + conditions.join(' AND ');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        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) {
 | 
					        } else if (DB._indicesMap.updated_at) {
 | 
				
			||||||
          sql += " ORDER BY \"updated_at\" DESC ";
 | 
					          sql += " ORDER BY 'updated_at' DESC ";
 | 
				
			||||||
        } else if (DB._indicesMap.created_at) {
 | 
					        } else if (DB._indicesMap.created_at) {
 | 
				
			||||||
          sql += " ORDER BY \"created_at\" DESC ";
 | 
					          sql += " ORDER BY 'created_at' DESC ";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (isFinite(params.limit)) {
 | 
					        if (isFinite(params.limit)) {
 | 
				
			||||||
          sql += " LIMIT " + parseInt(params.limit, 10);
 | 
					          sql += " LIMIT " + parseInt(params.limit, 10);
 | 
				
			||||||
@ -380,80 +561,6 @@ 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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "masterquest-sqlite3",
 | 
					  "name": "masterquest-sqlite3",
 | 
				
			||||||
  "version": "1.1.0",
 | 
					  "version": "1.2.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": {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user