Comparing version 1.9.1 to 1.9.2
@@ -839,3 +839,3 @@ var async = require('async'); | ||
var snapshot = startingSnapshot || new Snapshot(id, 0, null, undefined, null); | ||
var error = ot.applyOps(snapshot, ops, {_normalizeJson0Paths: true}); | ||
var error = ot.applyOps(snapshot, ops, {_normalizeLegacyJson0Ops: true}); | ||
callback(error, snapshot); | ||
@@ -842,0 +842,0 @@ }; |
@@ -41,2 +41,3 @@ function ShareDBError(code, message) { | ||
ERR_OP_VERSION_NEWER_THAN_CURRENT_SNAPSHOT: 'ERR_OP_VERSION_NEWER_THAN_CURRENT_SNAPSHOT', | ||
ERR_OT_LEGACY_JSON0_OP_CANNOT_BE_NORMALIZED: 'ERR_OT_LEGACY_JSON0_OP_CANNOT_BE_NORMALIZED', | ||
ERR_OT_OP_BADLY_FORMED: 'ERR_OT_OP_BADLY_FORMED', | ||
@@ -43,0 +44,0 @@ ERR_OT_OP_NOT_APPLIED: 'ERR_OT_OP_NOT_APPLIED', |
@@ -167,3 +167,12 @@ // This contains the master OT functions for the database. They look like | ||
var op = ops[index]; | ||
if (options._normalizeJson0Paths) normalizeJson0Paths(snapshot, op); | ||
if (options._normalizeLegacyJson0Ops) { | ||
try { | ||
normalizeLegacyJson0Ops(snapshot, op); | ||
} catch (error) { | ||
return new ShareDBError( | ||
ERROR_CODE.ERR_OT_LEGACY_JSON0_OP_CANNOT_BE_NORMALIZED, | ||
'Cannot normalize legacy json0 op' | ||
); | ||
} | ||
} | ||
snapshot.v = op.v; | ||
@@ -209,6 +218,6 @@ var error = exports.apply(snapshot, op); | ||
* when trying to rebuild a snapshot from old, committed ops that didn't | ||
* have this stricter validation. This method fixes up the op paths to | ||
* have this stricter validation. This method fixes up legacy ops to | ||
* pass the stricter validation | ||
*/ | ||
function normalizeJson0Paths(snapshot, json0Op) { | ||
function normalizeLegacyJson0Ops(snapshot, json0Op) { | ||
if (snapshot.type !== types.defaultType.uri) return; | ||
@@ -218,3 +227,5 @@ var components = json0Op.op; | ||
for (var i = 0; i < components.length; i++) { | ||
var path = components[i].p; | ||
var component = components[i]; | ||
if (typeof component.lm === 'string') component.lm = +component.lm; | ||
var path = component.p; | ||
var element = snapshot.data; | ||
@@ -221,0 +232,0 @@ for (var j = 0; j < path.length; j++) { |
{ | ||
"name": "sharedb", | ||
"version": "1.9.1", | ||
"version": "1.9.2", | ||
"description": "JSON OT database backend", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -223,13 +223,12 @@ var expect = require('chai').expect; | ||
query.once('changed', function() { | ||
expect(query.results).to.have.length(1); | ||
expect(query.results[0].id).to.equal('fido'); | ||
expect(query.results[0].data).to.eql({age: 3, owner: {name: 'jim'}}); | ||
done(); | ||
}); | ||
// Submit an op on a field not in the projection, where the op should | ||
// cause the doc to be included in the query results | ||
fido.submitOp({p: ['color'], od: 'gold', oi: 'black'}, null, function(err) { | ||
if (err) return done(err); | ||
setTimeout(function() { | ||
expect(query.results).to.have.length(1); | ||
expect(query.results[0].id).to.equal('fido'); | ||
expect(query.results[0].data).to.eql({age: 3, owner: {name: 'jim'}}); | ||
done(); | ||
}, 10); | ||
}); | ||
fido.submitOp({p: ['color'], od: 'gold', oi: 'black'}, null, util.errorHandler(done)); | ||
}); | ||
@@ -236,0 +235,0 @@ }); |
@@ -219,10 +219,19 @@ var expect = require('chai').expect; | ||
if (err) return done(err); | ||
var query = connection.createSubscribeQuery('dogs', matchAllDbQuery, null, function(err) { | ||
if (err) return done(err); | ||
var query = connection.createSubscribeQuery('dogs', matchAllDbQuery); | ||
query.on('error', done); | ||
query.once('ready', function() { | ||
connection.close(); | ||
connection2.get('dogs', 'fido').fetch(function(err) { | ||
if (err) return done(err); | ||
connection2.get('dogs', 'fido').del(); | ||
connection2.get('dogs', 'taco').on('error', done).create({age: 2}); | ||
process.nextTick(function() { | ||
async.parallel([ | ||
function(cb) { | ||
connection2.get('dogs', 'fido').del(cb); | ||
}, | ||
function(cb) { | ||
connection2.get('dogs', 'taco').create({age: 2}, cb); | ||
} | ||
], function(error) { | ||
if (error) return done(error); | ||
backend.connect(connection); | ||
@@ -232,3 +241,3 @@ }); | ||
}); | ||
query.on('error', done); | ||
var wait = 2; | ||
@@ -242,3 +251,3 @@ function finish() { | ||
} | ||
query.on('insert', function(docs) { | ||
query.once('insert', function(docs) { | ||
expect(util.pluck(docs, 'id')).eql(['taco']); | ||
@@ -248,3 +257,3 @@ expect(util.pluck(docs, 'data')).eql([{age: 2}]); | ||
}); | ||
query.on('remove', function(docs) { | ||
query.once('remove', function(docs) { | ||
expect(util.pluck(docs, 'id')).eql(['fido']); | ||
@@ -251,0 +260,0 @@ // We don't assert the value of data, because the del op could be |
@@ -444,12 +444,11 @@ var Backend = require('../../lib/backend'); | ||
describe('invalid json0 path', function() { | ||
describe('invalid json0v2 path', function() { | ||
beforeEach(function(done) { | ||
var doc = backend.connect().get('series', 'his-dark-materials'); | ||
doc.create([{title: 'Golden Compass'}], function(error) { | ||
if (error) return done(error); | ||
doc.submitOp({p: ['0', 'title'], od: 'Golden Compass', oi: 'Northern Lights'}, function(error) { | ||
if (error) return done(error); | ||
doc.submitOp({p: ['1'], li: {title: 'Subtle Knife'}}, done); | ||
}); | ||
}); | ||
async.series([ | ||
doc.create.bind(doc, [{title: 'Golden Compass'}]), | ||
doc.submitOp.bind(doc, {p: ['0', 'title'], od: 'Golden Compass', oi: 'Northern Lights'}), | ||
doc.submitOp.bind(doc, {p: ['1'], li: {title: 'Subtle Knife'}}), | ||
doc.submitOp.bind(doc, {p: ['1'], lm: '0'}) | ||
], done); | ||
}); | ||
@@ -481,3 +480,3 @@ | ||
it('fetches v2 with json0v2', function(done) { | ||
it('fetches a string-indexed list insertion with json0v2', function(done) { | ||
backend.connect().fetchSnapshot('series', 'his-dark-materials', 2, function(error, snapshot) { | ||
@@ -489,4 +488,15 @@ if (error) return done(error); | ||
}); | ||
it('fetches a list move using a string target', function(done) { | ||
backend.connect().fetchSnapshot('series', 'his-dark-materials', 4, function(error, snapshot) { | ||
if (error) return done(error); | ||
expect(snapshot.data).to.eql([ | ||
{title: 'Subtle Knife'}, | ||
{title: 'Northern Lights'} | ||
]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
579022
15365