Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0d6367b
build up an OR clause for reflexive many to many joins
particlebanana Dec 16, 2016
d272fc3
Merge pull request #1415 from balderdashy/reflexive-joins-patch
particlebanana Dec 16, 2016
0ba6d91
0.11.7-0
particlebanana Dec 16, 2016
d6ddf91
Fixes issue reported in #1429
luislobo Jan 10, 2017
8246a04
Fixes tests, depending on NPM version installed
luislobo Jan 10, 2017
2a7f892
remove unnecessary early return
particlebanana Jan 16, 2017
e5f0372
remove any populates from a count criteria
particlebanana Jan 16, 2017
ee30b94
ensure criteria piece exists
particlebanana Jan 16, 2017
bdfdfb8
remove coverage pieces that is failing in travis
particlebanana Jan 16, 2017
cd44c1b
remove coverage npm script
particlebanana Jan 16, 2017
edf79cd
remove after script for travis
particlebanana Jan 16, 2017
832c471
0.11.7-1
particlebanana Jan 16, 2017
f70f43f
0.11.7
sgress454 Jan 17, 2017
09a312b
Update method by which cacheKey for many-to-many-through queries is d…
sgress454 Jan 23, 2017
ee48ba8
Merge pull request #1435 from balderdashy/fix-issue-3946
sgress454 Jan 25, 2017
843b863
Use NPM-published wl-adapter-tests
sgress454 Jan 25, 2017
dd3b57f
Check adapters for compatibility with Waterline 0.11.x.
sgress454 Jan 25, 2017
0a84cbe
Merge pull request #1439 from balderdashy/check-adapter-version
sgress454 Jan 25, 2017
381dc38
Use tabs in Makefile
sgress454 Jan 25, 2017
de0ae21
For NPM >= 3, ensure waterline-adapter-tests/node_modules folder exis…
sgress454 Jan 25, 2017
f64a916
0.11.8
sgress454 Jan 25, 2017
72a01eb
Merge pull request #1432 from luislobo/0.11.x
particlebanana Feb 15, 2017
d824de9
0.11.9
particlebanana Feb 15, 2017
3b23e5b
use correct key for through table
particlebanana Mar 6, 2017
74ac225
Merge pull request #1458 from balderdashy/through-table-patch
particlebanana Mar 6, 2017
b89d889
loosen range on waterline-schema
particlebanana Mar 6, 2017
ceb446c
0.11.10
particlebanana Mar 6, 2017
30aa6ef
transform values returned from a destroy query if available
particlebanana Mar 8, 2017
55c5f0d
fix tests
particlebanana Mar 8, 2017
2ff8f3a
Merge pull request #1461 from balderdashy/patch-destroy-issue
particlebanana Mar 8, 2017
7bd3451
0.11.11
particlebanana Mar 8, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[Makefile]
indent_style = tab
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
.dist
coverage/
npm-debug.log
.idea
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ branches:
- master
- 0.11.x

after_script:
- npm run coverage && cat ./coverage/lcov.info | ./node_modules/.bin/codeclimate

addons:
code_climate:
repo_token: 351483555263cf9bcd2416c58b0e0ae6ca1b32438aa51bbab2c833560fb67cc0
Expand Down
19 changes: 9 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
ROOT=$(shell pwd)
NPMVERSION=$(shell npm --version | cut -f1 -d.)

test: test-unit test-integration

test-unit:
@echo "\nRunning unit tests..."
@NODE_ENV=test mocha test/integration test/structure test/support test/unit --recursive
@NODE_ENV=test node_modules/.bin/mocha test/integration test/structure test/support test/unit --recursive

ifeq "$(NPMVERSION)" "2"
test-integration:
@echo "\nRunning integration tests..."
rm -rf node_modules/waterline-adapter-tests/node_modules/waterline;
mkdir -p node_modules/waterline-adapter-tests/node_modules;
ln -s "$(ROOT)" node_modules/waterline-adapter-tests/node_modules/waterline;
@NODE_ENV=test node test/adapter/runner.js

coverage:
@echo "\n\nRunning coverage report..."
rm -rf coverage
@NODE_ENV=test ./node_modules/istanbul/lib/cli.js cover --report none --dir coverage/core ./node_modules/.bin/_mocha \
test/integration test/structure test/support test/unit -- --recursive
./node_modules/istanbul/lib/cli.js cover --report none --dir coverage/adapter test/adapter/runner.js
./node_modules/istanbul/lib/cli.js report
else
test-integration:
@echo "\nRunning integration tests..."
@NODE_ENV=test node test/adapter/runner.js
endif


.PHONY: coverage
24 changes: 21 additions & 3 deletions lib/waterline.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,27 @@ Waterline.prototype.initialize = function(options, cb) {
var self = this;

// Ensure a config object is passed in containing adapters
if (!options) throw new Error('Usage Error: function(options, callback)');
if (!options.adapters) throw new Error('Options object must contain an adapters object');
if (!options.connections) throw new Error('Options object must contain a connections object');
if (!options) { throw new Error('Usage Error: function(options, callback)'); }
if (!options.adapters) { throw new Error('Options object must contain an adapters object'); }
if (!options.connections) { throw new Error('Options object must contain a connections object'); }

// Check that the given adapter is compatible with Waterline 0.11.x.
try {
_.each(options.adapters, function(adapter) {
// Adapters meant for Waterline >= 0.12 will have an adapterApiVersion property, so if we
// see that then we know the adapter won't work with this version of Waterline.
if (!_.isUndefined(adapter.adapterApiVersion)) {
throw new Error(
'\n-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n'+
'Cannot initialize Waterline.\n'+
'The installed version of adapter `' + adapter.identity + '` is too new!\n' +
'Please try installing a version < 1.0.\n' +
'-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n');
}
});
} catch (e) {
return cb(e);
}

// Allow collections to be passed in to the initialize method
if (options.collections) {
Expand Down
2 changes: 1 addition & 1 deletion lib/waterline/model/lib/associationMethods/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ Add.prototype.createManyToMany = function(collection, attribute, pk, key, cb) {

// If this is a throughTable, look into the meta data cache for what key to use
if (collectionAttributes.throughTable) {
var cacheKey = collectionAttributes.throughTable[attribute.on + '.' + key] || collectionAttributes.throughTable[attribute.via + '.' + key];
var cacheKey = collectionAttributes.throughTable[self.collection.adapter.identity + '.' + key] || collectionAttributes.throughTable[attribute.via + '.' + key];
if (!cacheKey) {
return cb(new Error('Unable to find the proper cache key in the through table definition'));
}
Expand Down
15 changes: 8 additions & 7 deletions lib/waterline/model/lib/associationMethods/remove.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ var Remove = module.exports = function(collection, proto, records, cb) {
//
// In the future when transactions are available this will all be done on a single
// connection and can be re-written.
this.removeCollectionAssociations(records, cb);
this.removeCollectionAssociations(records, proto, cb);
};

/**
Expand Down Expand Up @@ -78,11 +78,11 @@ Remove.prototype.findPrimaryKey = function(attributes, values) {
* @api private
*/

Remove.prototype.removeCollectionAssociations = function(records, cb) {
Remove.prototype.removeCollectionAssociations = function(records, proto, cb) {
var self = this;

async.eachSeries(_.keys(records), function(associationKey, next) {
self.removeAssociations(associationKey, records[associationKey], next);
self.removeAssociations(associationKey, records[associationKey], proto, next);
},

function(err) {
Expand All @@ -103,7 +103,7 @@ Remove.prototype.removeCollectionAssociations = function(records, cb) {
* @api private
*/

Remove.prototype.removeAssociations = function(key, records, cb) {
Remove.prototype.removeAssociations = function(key, records, proto, cb) {
var self = this;

// Grab the collection the attribute references
Expand All @@ -115,7 +115,7 @@ Remove.prototype.removeAssociations = function(key, records, cb) {

// Limit Removes to 10 at a time to prevent the connection pool from being exhausted
async.eachLimit(records, 10, function(associationId, next) {
self.removeRecord(associatedCollection, schema, associationId, key, next);
self.removeRecord(associatedCollection, schema, associationId, key, proto, next);
}, cb);

};
Expand All @@ -130,7 +130,7 @@ Remove.prototype.removeAssociations = function(key, records, cb) {
* @api private
*/

Remove.prototype.removeRecord = function(collection, attribute, associationId, key, cb) {
Remove.prototype.removeRecord = function(collection, attribute, associationId, key, proto, cb) {
var self = this;

// Validate `values` is a correct primary key format
Expand Down Expand Up @@ -172,6 +172,7 @@ Remove.prototype.removeRecord = function(collection, attribute, associationId, k
var _values = {};

criteria[associationKey] = associationId;
criteria[attribute.on] = proto.id;
_values[attribute.on] = null;

collection.update(criteria, _values, function(err) {
Expand Down Expand Up @@ -233,7 +234,7 @@ Remove.prototype.removeManyToMany = function(collection, attribute, pk, key, cb)

// If this is a throughTable, look into the meta data cache for what key to use
if (collectionAttributes.throughTable) {
var cacheKey = collectionAttributes.throughTable[attribute.on + '.' + key] || collectionAttributes.throughTable[attribute.via + '.' + key];
var cacheKey = collectionAttributes.throughTable[self.collection.adapter.identity + '.' + key] || collectionAttributes.throughTable[attribute.via + '.' + key];
if (!cacheKey) {
return cb(new Error('Unable to find the proper cache key in the through table definition'));
}
Expand Down
10 changes: 10 additions & 0 deletions lib/waterline/query/dql/count.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,15 @@ module.exports = function(criteria, options, cb) {
// Transform Search Criteria
criteria = this._transformer.serialize(criteria);

// Remove any joins from the count criteria. They won't have any effect on the
// number of results found.
if (_.isArray(criteria.joins)) {
delete criteria.joins;
}

if (criteria.where && _.isArray(criteria.where.joins)) {
delete criteria.where.joins;
}

this.adapter.count(criteria, cb);
};
43 changes: 37 additions & 6 deletions lib/waterline/query/dql/destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ module.exports = function(criteria, cb) {

function destroyJoinTableRecords(item, next) {
var collection = self.waterline.collections[item];
var refKey;
var refKey = [];

Object.keys(collection._attributes).forEach(function(key) {
var attr = collection._attributes[key];
if (attr.references !== self.identity) return;
refKey = key;
refKey.push(key);
});

// If no refKey return, this could leave orphaned join table values but it's better
// than crashing.
if (!refKey) return next();
if (!refKey.length) return next();

// Make sure we don't return any undefined pks
var mappedValues = result.reduce(function(memo, vals) {
Expand All @@ -109,7 +109,22 @@ module.exports = function(criteria, cb) {
var criteria = {};

if (mappedValues.length > 0) {
criteria[refKey] = mappedValues;
// Handle reflexive associations by building up an OR clause.
if (refKey.length > 1) {
var orCriteria = [];
_.each(refKey, function(columnName) {
var where = {};
where[columnName] = mappedValues;
orCriteria.push(where);
});

criteria = {
or: orCriteria
};
} else {
criteria[_.first(refKey)] = mappedValues;
}

collection.destroy(criteria).exec(next);
} else {
return next();
Expand All @@ -123,9 +138,25 @@ module.exports = function(criteria, cb) {
});

function after() {
callbacks.afterDestroy(self, result, function(err) {

// If no result was returned, default to empty array
if (!result) {
result = [];
}

// If values is not an array, return an array
if (!Array.isArray(result)) {
result = [result];
}

// Unserialize each value
var transformedValues = result.map(function(value) {
return self._transformer.unserialize(value);
});

callbacks.afterDestroy(self, transformedValues, function(err) {
if (err) return cb(err);
cb(null, result);
cb(null, transformedValues);
});
}

Expand Down
2 changes: 0 additions & 2 deletions lib/waterline/query/finders/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ module.exports = {
if (!hasOwnProperty(search, join.alias)) return;
delete search[join.alias];
});
return;
}

if (!hasOwnProperty(tmpCriteria, join.alias)) return;
Expand Down Expand Up @@ -308,7 +307,6 @@ module.exports = {
if (!hasOwnProperty(search, join.alias)) return;
delete search[join.alias];
});
return;
}

if (!hasOwnProperty(tmpCriteria, join.alias)) return;
Expand Down
2 changes: 1 addition & 1 deletion lib/waterline/utils/nestedOperations/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ function buildParentRemoveOperations(parent, operations) {
model: child.identity,
criteria: searchCriteria,
keyName: attribute.on,
nullify: !hop(child, 'junctionTable')
nullify: !hop(child, 'throughTable')
};


Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "waterline",
"description": "An ORM for Node.js and the Sails framework.",
"version": "0.11.6",
"version": "0.11.11",
"homepage": "http://waterlinejs.org",
"contributors": [
{
Expand Down Expand Up @@ -30,7 +30,7 @@
"prompt": "0.2.14",
"switchback": "2.0.0",
"waterline-criteria": "~0.11.2",
"waterline-schema": "0.2.0"
"waterline-schema": "~0.2.1"
},
"devDependencies": {
"codeclimate-test-reporter": "0.3.1",
Expand All @@ -40,7 +40,7 @@
"mocha": "2.4.5",
"sails-memory": "balderdashy/sails-memory",
"should": "8.2.1",
"waterline-adapter-tests": "balderdashy/waterline-adapter-tests#0.11.x"
"waterline-adapter-tests": "~0.11.2"
},
"keywords": [
"mvc",
Expand All @@ -59,8 +59,7 @@
"scripts": {
"test": "make test",
"prepublish": "npm prune",
"browserify": "rm -rf .dist && mkdir .dist && browserify lib/waterline.js -s Waterline | uglifyjs > .dist/waterline.min.js",
"coverage": "make coverage"
"browserify": "rm -rf .dist && mkdir .dist && browserify lib/waterline.js -s Waterline | uglifyjs > .dist/waterline.min.js"
},
"engines": {
"node": ">=0.10.0"
Expand Down
19 changes: 12 additions & 7 deletions test/integration/model/association.remove.hasMany.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,18 @@ describe('Model', function() {
waterline.loadCollection(Preference);

var _values = [
{ id: 1, preference: [{ foo: 'bar' }, { foo: 'foobar' }] },
{ id: 2, preference: [{ foo: 'a' }, { foo: 'b' }] },
{ id: 1, preference: [{ id: 10, foo: 'bar' }, { id: 20, foo: 'foobar' }] },
{ id: 2, preference: [{ id: 30, foo: 'a' }, { id: 40, foo: 'b' }] },
];

var adapterDef = {
find: function(con, col, criteria, cb) { return cb(null, _values); },
update: function(con, col, criteria, values, cb) {
if(col === 'preference') {
prefValues.push({ id: criteria.where.id, values: values });
prefValues.push({
id: criteria.where.id,
assoc: criteria.where.user,
values: values });
}

return cb(null, values);
Expand Down Expand Up @@ -80,16 +83,18 @@ describe('Model', function() {

var person = models[0];

person.preferences.remove(1);
person.preferences.remove(2);
person.preferences.remove(10);
person.preferences.remove(20);

person.save(function(err) {
if(err) return done(err);

assert(prefValues.length === 2);
assert(prefValues[0].id === 1);
assert(prefValues[0].id === 10);
assert(prefValues[0].assoc === 1);
assert(prefValues[0].values.user === null);
assert(prefValues[1].id === 2);
assert(prefValues[1].id === 20);
assert(prefValues[1].assoc === 1);
assert(prefValues[1].values.user === null);

done();
Expand Down
8 changes: 4 additions & 4 deletions test/integration/model/destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('Model', function() {

waterline.loadCollection(Collection);

var adapterDef = { destroy: function(con, col, options, cb) { return cb(null, true); }};
var adapterDef = { destroy: function(con, col, options, cb) { return cb(null, [{ id: 1, first_name: 'foo', last_name: 'bar' }]); }};

var connections = {
'my_foo': {
Expand All @@ -46,12 +46,12 @@ describe('Model', function() {
// TEST METHODS
////////////////////////////////////////////////////

it('should pass status from the adapter destroy method', function(done) {
it('should pass data from the adapter destroy method', function(done) {
var person = new collection._model({ id: 1, first_name: 'foo', last_name: 'bar' });

person.destroy(function(err, status) {
person.destroy(function(err, records) {
assert(!err);
assert(status === true);
assert.equal(records[0].last_name, 'bar');
done();
});
});
Expand Down
Loading