waterline
Advanced tools
Comparing version 0.0.0 to 0.0.1
@@ -34,2 +34,6 @@ var _ = require('underscore'); | ||
////////////////////////////////////////////////////////////////////// | ||
// DDL | ||
////////////////////////////////////////////////////////////////////// | ||
this.define = function(collectionName, definition, cb) { | ||
@@ -86,9 +90,11 @@ | ||
////////////////////////////////////////////////////////////////////// | ||
// DQL | ||
////////////////////////////////////////////////////////////////////// | ||
this.create = function(collectionName, values, cb) { | ||
adapter.create ? adapter.create(collectionName,values,cb) : cb(); | ||
}; | ||
this.find = function(collectionName, criteria, cb) { | ||
criteria = normalizeCriteria(criteria); | ||
adapter.find ? adapter.find(collectionName,criteria,cb) : cb(); | ||
this.find = function(collectionName, options, cb) { | ||
options = normalizeCriteria(options); | ||
adapter.find ? adapter.find(collectionName,options,cb) : cb(); | ||
}; | ||
@@ -104,2 +110,24 @@ this.update = function(collectionName, criteria, values, cb) { | ||
////////////////////////////////////////////////////////////////////// | ||
// Convenience methods (overwritable in adapters) | ||
////////////////////////////////////////////////////////////////////// | ||
this.findOrCreate = function (collectionName, criteria, values, cb) { | ||
criteria = normalizeCriteria(criteria); | ||
if (adapter.findOrCreate) adapter.findOrCreate(collectionName, criteria, values, cb); | ||
else throw "TODO! :: This functionality will be released in an upcoming version."; | ||
}; | ||
this.findAndUpdate = function (collectionName, criteria, values, cb) { | ||
criteria = normalizeCriteria(criteria); | ||
if (adapter.findAndUpdate) adapter.findAndUpdate(collectionName, criteria, values, cb); | ||
else this.update(collectionName, criteria, values, cb); | ||
}; | ||
this.findAndDestroy = function (collectionName, criteria, cb) { | ||
criteria = normalizeCriteria(criteria); | ||
if (adapter.findAndDestroy) adapter.findAndDestroy(collectionName, criteria, cb); | ||
else this.destroy(collectionName, criteria, cb); | ||
}; | ||
// Begin an atomic transaction | ||
@@ -233,2 +261,7 @@ // lock models in collection which fit criteria (if criteria is null, lock all) | ||
function normalizeCriteria (criteria) { | ||
// Empty undefined values from criteria object | ||
_.each(criteria,function(val,key) { | ||
if (val === undefined) delete criteria[key]; | ||
}); | ||
if((_.isFinite(criteria) || _.isString(criteria)) && +criteria > 0) { | ||
@@ -242,3 +275,18 @@ criteria = { | ||
} | ||
if (!criteria.where && !criteria.limit && | ||
!criteria.skip && !criteria.offset && | ||
!criteria.order) { | ||
console.log("CRITERIAAAAAA",criteria); | ||
criteria = { where: criteria }; | ||
console.log("CRITERIAAAAAA2222",criteria); | ||
} | ||
// If any item in criteria is a parsable finite number, use that | ||
for (var attrName in criteria.where) { | ||
if (Math.pow(+criteria.where[attrName],2) > 0) { | ||
criteria.where[attrName] = +criteria.where[attrName]; | ||
} | ||
} | ||
return criteria; | ||
} |
@@ -49,4 +49,4 @@ var _ = require('underscore'); | ||
// Call find method in adapter | ||
this.find = function(criteria, cb) { | ||
return this.adapter.find(this.identity,criteria,cb); | ||
this.find = function(options, cb) { | ||
return this.adapter.find(this.identity,options,cb); | ||
}; | ||
@@ -62,2 +62,12 @@ // Call update method in adapter | ||
this.findOrCreate = function (criteria, values, cb) { | ||
return this.adapter.findOrCreate(this.identity,criteria,values,cb); | ||
}; | ||
this.findAndUpdate = function (criteria, values, cb) { | ||
return this.adapter.findAndUpdate(this.identity, criteria, values, cb); | ||
}; | ||
this.findAndDestroy = function (criteria, cb) { | ||
return this.adapter.findAndDestroy(this.identity, criteria, cb); | ||
}; | ||
this.lock = function(criteria, cb) { | ||
@@ -70,2 +80,16 @@ this.adapter.lock(this.identity,criteria,cb); | ||
////////////////////////////////////////// | ||
// Utility methods | ||
////////////////////////////////////////// | ||
// Return a trimmed set of the specified attributes | ||
// with only the attributes which actually exist in the server-side model | ||
this.filter = function(params) { | ||
var trimmedParams = _.objFilter(params, function(value, name) { | ||
return _.contains(_.keys(this.attributes), name); | ||
}, this); | ||
return trimmedParams; | ||
}; | ||
this.trimParams = this.filter; | ||
// Bind instance methods to collection | ||
@@ -72,0 +96,0 @@ _.bindAll(definition); |
{ | ||
"name": "waterline", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"description": "Adaptable data access layer for Node.js", | ||
@@ -32,7 +32,8 @@ "main": "waterline.js", | ||
"dirty": "~0.9.6", | ||
"underscore": "~1.4.2", | ||
"underscore": "=1.4.3", | ||
"parley": "0.0.1203", | ||
"mysql": "~2.0.0-alpha4", | ||
"node-uuid": "~1.4.0" | ||
"node-uuid": "~1.4.0", | ||
"require-all": "0.0.5" | ||
} | ||
} |
// Test DirtyAdapter | ||
require('./crud.test.js')(require('./adapters/DirtyAdapter.js')); | ||
require('./crud.test.js')(require('../adapters/DirtyAdapter.js')); |
@@ -5,2 +5,3 @@ // Dependencies | ||
var assert = require("assert"); | ||
var buildDictionary = require('../buildDictionary.js'); | ||
@@ -12,3 +13,3 @@ | ||
// Grab included adapters and test models | ||
var adapters = buildDictionary(__dirname + '/adapters', /(.+Adapter)\.js$/, /Adapter/); | ||
var adapters = {}; | ||
var models = buildDictionary(__dirname + '/models', /(.+)\.js$/); | ||
@@ -21,27 +22,2 @@ | ||
}); | ||
}); | ||
// buildDictionary () | ||
// Go through each object, include the code, and determine its identity | ||
// | ||
// @dirname :: the path to the source directory | ||
// @filter :: the filter regex | ||
// $replaceExpr :: the replace regex | ||
function buildDictionary (dirname,filter,replaceExpr) { | ||
var files = require('require-all')({ | ||
dirname: dirname, | ||
filter: filter | ||
}); | ||
var objects = {}; | ||
_.each(files,function (object, filename) { | ||
// If no 'identity' attribute was provided, | ||
// take a guess based on the filename | ||
if (!object.identity) { | ||
if (!replaceExpr) object.identity = filename.toLowerCase(); | ||
else object.identity = filename.replace(replaceExpr, "").toLowerCase(); | ||
} | ||
objects[object.identity] = object; | ||
}); | ||
return objects; | ||
} | ||
}); |
@@ -9,3 +9,3 @@ /*--------------------- | ||
exports.scheme = 'alter'; | ||
// exports.scheme = 'alter'; | ||
@@ -12,0 +12,0 @@ exports.attributes = { |
// Test MySQLAdapter | ||
// require('./crud.test.js')(require('./adapters/MySQLAdapter.js')); | ||
// require('./crud.test.js')(require('../adapters/MySQLAdapter.js')); |
198
waterline.js
@@ -11,2 +11,5 @@ // Dependencies | ||
// Util | ||
var buildDictionary = require('./buildDictionary.js'); | ||
// mock sails for now | ||
@@ -18,2 +21,5 @@ var config = { | ||
// Include built-in adapters | ||
var builtInAdapters = buildDictionary(__dirname + '/adapters', /(.+Adapter)\.js$/, /Adapter/); | ||
/** | ||
@@ -25,2 +31,5 @@ * Prepare waterline to interact with adapters | ||
// Merge passed-in adapters with default adapters | ||
adapters = _.extend(builtInAdapters,adapters || {}); | ||
// Error aggregator obj | ||
@@ -43,2 +52,3 @@ var errs; | ||
// associate each model with its adapter and sync its schema | ||
collections = collections || {}; | ||
for (var collectionName in collections) { | ||
@@ -73,1 +83,189 @@ var collection = collections[collectionName]; | ||
//////////////////////////////////////////////////////////////////////// | ||
// UTILS | ||
//////////////////////////////////////////////////////////////////////// | ||
// Mix in some commonly used underscore fns | ||
_.mixin({ | ||
// Really LOUD version of console.log.debug | ||
shout: function() { | ||
var args = _.values(arguments); | ||
console.log("\n"); | ||
if(args.length == 1) { | ||
console.log("*", args[0]); | ||
} else { | ||
console.log("*", args.shift()); | ||
console.log("------------------------------"); | ||
args.length > 0 && _.each(args, function(arg) { | ||
console.log(" => ", arg, " (" + (typeof arg) + ")"); | ||
}); | ||
} | ||
}, | ||
// Get the file extension | ||
fileExtension: function(str) { | ||
if(str === null) return ''; | ||
var pieces = String(str).split('.'); | ||
return pieces.length > 1 ? _.last(pieces) : ''; | ||
}, | ||
// Pretty rendering of things like: 1st, 2nd, 3rd, 4th | ||
th: function(integer) { | ||
if(_.isFinite(+integer) && Math.floor(+integer) === +integer) { | ||
var lastDigit = +integer % 10; | ||
var lastTwoDigits = +integer % 100; | ||
var response = integer + ""; | ||
// Handle n-teen case | ||
if(lastTwoDigits >= 11 && lastTwoDigits <= 13) { | ||
return response + "th"; | ||
} | ||
// Handle general case | ||
switch(lastDigit) { | ||
case 1: | ||
return response + "st"; | ||
case 2: | ||
return response + "nd"; | ||
case 3: | ||
return response + "rd"; | ||
default: | ||
return response + "th"; | ||
} | ||
} else { | ||
sails.log.debug("You specified: ", integer); | ||
throw new Error("But _.th only works on integers!"); | ||
} | ||
}, | ||
// ### _.objMap | ||
// _.map for objects, keeps key/value associations | ||
objMap: function(input, mapper, context) { | ||
return _.reduce(input, function(obj, v, k) { | ||
obj[k] = mapper.call(context, v, k, input); | ||
return obj; | ||
}, {}, context); | ||
}, | ||
// ### _.objFilter | ||
// _.filter for objects, keeps key/value associations | ||
// but only includes the properties that pass test(). | ||
objFilter: function(input, test, context) { | ||
return _.reduce(input, function(obj, v, k) { | ||
if(test.call(context, v, k, input)) { | ||
obj[k] = v; | ||
} | ||
return obj; | ||
}, {}, context); | ||
}, | ||
// ### _.objReject | ||
// | ||
// _.reject for objects, keeps key/value associations | ||
// but does not include the properties that pass test(). | ||
objReject: function(input, test, context) { | ||
return _.reduce(input, function(obj, v, k) { | ||
if(!test.call(context, v, k, input)) { | ||
obj[k] = v; | ||
} | ||
return obj; | ||
}, {}, context); | ||
}, | ||
/** | ||
* Usage: | ||
* obj -> the object | ||
* arguments* -> other arguments can be specified to be invoked on each of the functions | ||
*/ | ||
objInvoke: function(obj) { | ||
var args = _.toArray(arguments).shift(); | ||
return _.objMap(obj, function(fn) { | ||
return fn(args); | ||
}); | ||
} | ||
}); | ||
// Recursive underscore methods | ||
_.recursive = { | ||
// fn(value,keyChain) | ||
all: function(collection, fn, maxDepth) { | ||
if(!_.isObject(collection)) { | ||
return true; | ||
} | ||
// Default value for maxDepth | ||
maxDepth = maxDepth || 50; | ||
// Kick off recursive function | ||
return _all(collection, null, [], fn, 0); | ||
function _all(item, key, keyChain, fn, depth) { | ||
var lengthenedKeyChain = []; | ||
if(depth > maxDepth) { | ||
throw new Error('Depth of object being parsed exceeds maxDepth (). Maybe it links to itself?'); | ||
} | ||
// If the key is null, this is the root item, so skip this step | ||
// Descend | ||
if(key !== null && keyChain) { | ||
lengthenedKeyChain = keyChain.slice(0); | ||
lengthenedKeyChain.push(key); | ||
} | ||
// If the current item is a collection | ||
if(_.isObject(item)) { | ||
return _.all(item, function(subval, subkey) { | ||
return _all(subval, subkey, lengthenedKeyChain, fn, depth + 1); | ||
}); | ||
} | ||
// Leaf items land here and execute the iterator | ||
else { | ||
return fn(item, lengthenedKeyChain); | ||
} | ||
} | ||
}, | ||
// fn(original,newOne,anotherNewOne,...) | ||
extend: function(original, newObj) { | ||
// TODO: make this work for more than one newObj | ||
// var newObjects = _.toArray(arguments).shift(); | ||
return _.extend(original, _.objMap(newObj, function(newVal, key) { | ||
var oldVal = original[key]; | ||
// If the new value is a non-object or array, | ||
// or the old value is a non-object or array, use it | ||
if(_.isArray(newVal) || !_.isObject(newVal) || _.isArray(oldVal) || !_.isObject(oldVal)) { | ||
return !_.isUndefined(newVal) ? newVal : oldVal; | ||
} | ||
// Otherwise, we have to descend recursively | ||
else { | ||
return _.recursive.extend(oldVal, newVal); | ||
} | ||
})); | ||
}, | ||
// fn(original,newOne,anotherNewOne,...) | ||
defaults: function(original, newObj) { | ||
// TODO: make this work for more than one newObj | ||
// var newObjects = _.toArray(arguments).shift(); | ||
return _.extend(original, _.objMap(newObj, function(newVal, key) { | ||
var oldVal = original[key]; | ||
// If the new value is a non-object or array, | ||
// or the old value is a non-object or array, use it | ||
if(_.isArray(newVal) || !_.isObject(newVal) || _.isArray(oldVal) || !_.isObject(oldVal)) { | ||
return !_.isUndefined(oldVal) ? oldVal : newVal; | ||
} | ||
// Otherwise, we have to descend recursively | ||
else { | ||
return _.recursive.extend(oldVal, newVal); | ||
} | ||
})); | ||
} | ||
}; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
40104
6
15
1096
1
+ Addedrequire-all@0.0.5
+ Addedrequire-all@0.0.5(transitive)
- Removedunderscore@1.4.4(transitive)
Updatedunderscore@=1.4.3