Comparing version 0.3.2 to 0.4.0
@@ -24,2 +24,3 @@ // Copyright (c) 2015 Uber Technologies, Inc. | ||
var _ = require('lodash'); | ||
var AbstractQueryOperation = require('./abstract_query_operation'); | ||
@@ -31,2 +32,3 @@ var async = require('async'); | ||
var Ok = require('rust-result').Ok; | ||
var Query = require('./query'); | ||
var util = require('util'); | ||
@@ -37,2 +39,3 @@ | ||
this.operator = Query.CONST.OPERATOR_PUSH; | ||
this.prepared = false; | ||
@@ -78,3 +81,3 @@ this.executing = false; | ||
return doneCallback(new Error( | ||
'Illegal $push modification at keyPath \'' + | ||
'Illegal ' + this.operator + ' modification at keyPath \'' + | ||
keyPath + '\' can only use $each without any other keys on object')); | ||
@@ -86,3 +89,3 @@ } | ||
return doneCallback(new Error( | ||
'Illegal $push modification at keyPath \'' + | ||
'Illegal ' + this.operator + ' modification at keyPath \'' + | ||
keyPath + '\' $each expects an array value')); | ||
@@ -96,3 +99,3 @@ } | ||
this._getCollectionPropertyValue('$push', property, keyPath, valueArray, function(err, uuids, fragments) { | ||
this._getCollectionPropertyValue(this.operator, property, keyPath, valueArray, function(err, uuids, fragments) { | ||
if (err) { | ||
@@ -167,3 +170,3 @@ return doneCallback(err); | ||
return doneCallback(new Error( | ||
'Illegal $push modification at keyPath \'' + keyPath + | ||
'Illegal ' + this.operator + ' modification at keyPath \'' + keyPath + | ||
'\' no such ModelObject exists at keyPath')); | ||
@@ -177,17 +180,34 @@ } | ||
// Make sure this operation is push by prepending all existing UUIDs | ||
// Bind the fragments as final properties | ||
var properties = lateBoundSyncFragment.properties; | ||
var key = Object.keys(properties)[0]; | ||
var uuids = properties[key]; | ||
properties[key] = target[key].map(function(element) { | ||
return element.uuid; | ||
}).concat(uuids); | ||
this._bindFragmentProperties(target, key, properties); | ||
// If the properties didn't change then remove the entry from the SyncFragment | ||
var setValues = properties[key]; | ||
var targetValues = target[key]; | ||
var changes = false; | ||
if (setValues.length !== targetValues) { | ||
changes = true; | ||
} else { | ||
_.each(setValues, function(value, index) { | ||
if (value !== targetValues[index].uuid) { | ||
changes = true; | ||
return false; | ||
} | ||
}); | ||
} | ||
if (!changes) { | ||
delete properties[key]; | ||
} | ||
doneCallback(); | ||
}, nextCallback); | ||
}.bind(this), nextCallback); | ||
}.bind(this), | ||
function applySyncFragments(nextCallback) { | ||
var syncFragments = this.lateBoundChangeSyncFragments; | ||
var syncFragments = this.lateBoundChangeSyncFragments.filter(function(syncFragment) { | ||
return Object.keys(syncFragment.properties).length > 0; | ||
}); | ||
syncFragments = syncFragments.concat(this.lateBoundAddSyncFragments); | ||
@@ -211,1 +231,9 @@ var options = this.options; | ||
}; | ||
PushQueryOperation.prototype._bindFragmentProperties = function(target, key, properties) { | ||
var uuids = properties[key]; | ||
properties[key] = target[key].map(function(element) { | ||
return element.uuid; | ||
}).concat(uuids); | ||
}; | ||
@@ -25,2 +25,3 @@ // Copyright (c) 2015 Uber Technologies, Inc. | ||
var _ = require('lodash'); | ||
var AddToSetQueryOperation = require('./add_to_set_query_operation'); | ||
var async = require('async'); | ||
@@ -34,4 +35,5 @@ var PullQueryOperation = require('./pull_query_operation'); | ||
var CONST = {}; | ||
CONST.OPERATOR_ADD_TO_SET = '$addToSet'; | ||
CONST.OPERATOR_PULL = '$pull'; | ||
CONST.OPERATOR_PUSH = '$push'; | ||
CONST.OPERATOR_PULL = '$pull'; | ||
CONST.OPERATOR_SET = '$set'; | ||
@@ -111,4 +113,4 @@ CONST = Object.freeze(CONST); | ||
switch (operator) { | ||
case CONST.OPERATOR_PUSH: | ||
operation = new PushQueryOperation(_.extend(options, { | ||
case CONST.OPERATOR_ADD_TO_SET: | ||
operation = new AddToSetQueryOperation(_.extend(options, { | ||
typeClass: modelObject.constructor, | ||
@@ -118,2 +120,3 @@ modification: modification | ||
break; | ||
case CONST.OPERATOR_PULL: | ||
@@ -125,2 +128,10 @@ operation = new PullQueryOperation(_.extend(options, { | ||
break; | ||
case CONST.OPERATOR_PUSH: | ||
operation = new PushQueryOperation(_.extend(options, { | ||
typeClass: modelObject.constructor, | ||
modification: modification | ||
})); | ||
break; | ||
case CONST.OPERATOR_SET: | ||
@@ -127,0 +138,0 @@ operation = new SetQueryOperation(_.extend(options, { |
@@ -469,2 +469,15 @@ // Copyright (c) 2015 Uber Technologies, Inc. | ||
async.waterfall([ | ||
function verifyDoesNotAlreadyExist(nextCallback) { | ||
this.getModelObjectByUUID(fragment.objectUUID, function(err, modelObject) { | ||
if (err) { | ||
return nextCallback(err); | ||
} | ||
if (modelObject) { | ||
return nextCallback(new Error( | ||
'ModelObject with UUID \'' + fragment.objectUUID + '\' already exists')); | ||
} | ||
nextCallback(); | ||
}); | ||
}.bind(this), | ||
function getModelObjectType(nextCallback) { | ||
@@ -471,0 +484,0 @@ var rootModelObjectType = this._rootModelObjectConstructor; |
{ | ||
"name": "jetstream", | ||
"version": "0.3.2", | ||
"version": "0.4.0", | ||
"description": "Jetstream Sync server framework to sync local and remote models", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -37,2 +37,3 @@ // Copyright (c) 2015 Uber Technologies, Inc. | ||
require('./procedures/remote_http_sync_procedure'); | ||
require('./query/add_to_set_query_operation'); | ||
require('./query/key_path_notation'); | ||
@@ -39,0 +40,0 @@ require('./query/pull_query_operation'); |
@@ -97,2 +97,104 @@ // Copyright (c) 2015 Uber Technologies, Inc. | ||
test(thing('should be able to push an existing ModelObject by just UUID'), function t(assert) { | ||
var room = createTestChatRoom(); | ||
var testAuthor = createTestUser(); | ||
testAuthor.username = 'PushQueryTestUser'; | ||
room.users = [testAuthor]; | ||
var testExistingMessage = createTestMessage(); | ||
room.messages = [testExistingMessage]; | ||
async.waterfall([ | ||
function setRoot(nextCallback) { | ||
var scope = new Scope({name: 'ChatRoomScope'}); | ||
scope.setRoot(room, function(err) { | ||
nextCallback(err, scope); | ||
}); | ||
}, | ||
function executeUpdate(scope, nextCallback) { | ||
scope.update({}, { | ||
$push: { | ||
messages: testExistingMessage.uuid | ||
} | ||
}, nextCallback); | ||
}, | ||
function verifyQueryResult(result, nextCallback) { | ||
assert.equal(room.messages.length, 2); | ||
assert.equal(room.messages.objectAtIndex(0).uuid, testExistingMessage.uuid); | ||
assert.equal(room.messages.objectAtIndex(0).author, testExistingMessage.author); | ||
assert.equal(room.messages.objectAtIndex(0).text, testExistingMessage.text); | ||
assert.equal(room.messages.objectAtIndex(1).uuid, testExistingMessage.uuid); | ||
assert.equal(room.messages.objectAtIndex(1).author, testExistingMessage.author); | ||
assert.equal(room.messages.objectAtIndex(1).text, testExistingMessage.text); | ||
assert.equal(result.matched.length, 1); | ||
assert.equal(result.matched[0].uuid, room.uuid); | ||
assert.equal(result.matched[0].clsName, room.typeName); | ||
assert.equal(result.created.length, 0); | ||
assert.equal(result.modified.length, 1); | ||
assert.equal(result.modified[0].uuid, room.uuid); | ||
assert.equal(result.modified[0].clsName, room.typeName); | ||
nextCallback(); | ||
} | ||
], function(err) { | ||
assert.ifError(err); | ||
assert.end(); | ||
}); | ||
}); | ||
test(thing('should not be able to push a "new" ModelObject with an existing UUID'), function t(assert) { | ||
var room = createTestChatRoom(); | ||
var testAuthor = createTestUser(); | ||
testAuthor.username = 'PushQueryTestUser'; | ||
room.users = [testAuthor]; | ||
var testExistingMessage = createTestMessage(); | ||
room.messages = [testExistingMessage]; | ||
async.waterfall([ | ||
function setRoot(nextCallback) { | ||
var scope = new Scope({name: 'ChatRoomScope'}); | ||
scope.setRoot(room, function(err) { | ||
nextCallback(err, scope); | ||
}); | ||
}, | ||
function executeUpdate(scope, nextCallback) { | ||
scope.update({}, { | ||
$push: { | ||
messages: { | ||
$uuid: testExistingMessage.uuid, | ||
author: testAuthor.uuid, | ||
postedAt: new Date(), | ||
text: 'Overwrite message' | ||
} | ||
} | ||
}, nextCallback); | ||
}, | ||
function verifyQueryResult(result, nextCallback) { | ||
assert.equal(result.writeErrors.length, 1); | ||
assert.ok(new RegExp(testExistingMessage.uuid).test(result.writeErrors[0].message)); | ||
assert.ok(/already exists/.test(result.writeErrors[0].message)); | ||
nextCallback(); | ||
} | ||
], function(err) { | ||
assert.ifError(err); | ||
assert.end(); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
470469
98
10486