Implement `findOrCreate` for memory connector
This commit is contained in:
parent
a5150265ec
commit
ba7161b39e
|
@ -189,7 +189,7 @@ Memory.prototype.define = function defineModel(definition) {
|
||||||
if(!this.collection(m)) this.initCollection(m);
|
if(!this.collection(m)) this.initCollection(m);
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.create = function create(model, data, options, callback) {
|
Memory.prototype._createSync = function(model, data, fn) {
|
||||||
// FIXME: [rfeng] We need to generate unique ids based on the id type
|
// FIXME: [rfeng] We need to generate unique ids based on the id type
|
||||||
// FIXME: [rfeng] We don't support composite ids yet
|
// FIXME: [rfeng] We don't support composite ids yet
|
||||||
var currentId = this.collectionSeq(model);
|
var currentId = this.collectionSeq(model);
|
||||||
|
@ -207,18 +207,27 @@ Memory.prototype.create = function create(model, data, options, callback) {
|
||||||
var idName = this.idName(model);
|
var idName = this.idName(model);
|
||||||
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
|
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
|
||||||
this.setIdValue(model, data, id);
|
this.setIdValue(model, data, id);
|
||||||
if(!this.collection(model)) {
|
if (!this.collection(model)) {
|
||||||
this.collection(model, {});
|
this.collection(model, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.collection(model)[id]) {
|
if (this.collection(model)[id])
|
||||||
return process.nextTick(function() {
|
return fn(new Error('Duplicate entry for ' + model + '.' + idName));
|
||||||
callback(new Error('Duplicate entry for ' + model + '.' + idName));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.collection(model)[id] = serialize(data);
|
this.collection(model)[id] = serialize(data);
|
||||||
this.saveToFile(id, callback);
|
fn(null, id);
|
||||||
|
};
|
||||||
|
|
||||||
|
Memory.prototype.create = function create(model, data, options, callback) {
|
||||||
|
var self = this;
|
||||||
|
this._createSync(model, data, function(err, id) {
|
||||||
|
if (err) {
|
||||||
|
return process.nextTick(function() {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
self.saveToFile(id, callback);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.updateOrCreate = function (model, data, options, callback) {
|
Memory.prototype.updateOrCreate = function (model, data, options, callback) {
|
||||||
|
@ -237,6 +246,36 @@ Memory.prototype.updateOrCreate = function (model, data, options, callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Memory.prototype.findOrCreate = function(model, filter, data, callback) {
|
||||||
|
var self = this;
|
||||||
|
var nodes = self._findAllSkippingIncludes(model, filter);
|
||||||
|
var found = nodes[0];
|
||||||
|
|
||||||
|
if(!found) {
|
||||||
|
// Calling _createSync to update the collection in a sync way and to guarantee to create it in the same turn of even loop
|
||||||
|
return self._createSync(model, data, function(err, id) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
self.saveToFile(id, function(err, id) {
|
||||||
|
self.setIdValue(model, data, id);
|
||||||
|
callback(err, data, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filter || !filter.include) {
|
||||||
|
return process.nextTick(function() {
|
||||||
|
callback(null, found, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self._models[model].model.include(nodes[0], filter.include, {}, function(err, nodes) {
|
||||||
|
process.nextTick(function() {
|
||||||
|
if (err) return callback(err);
|
||||||
|
callback(null, nodes[0], false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Memory.prototype.save = function save(model, data, options, callback) {
|
Memory.prototype.save = function save(model, data, options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var id = this.getIdValue(model, data);
|
var id = this.getIdValue(model, data);
|
||||||
|
@ -312,8 +351,7 @@ function getValue(obj, path) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory.prototype.all = function all(model, filter, options, callback) {
|
Memory.prototype._findAllSkippingIncludes = function(model, filter) {
|
||||||
var self = this;
|
|
||||||
var nodes = Object.keys(this.collection(model)).map(function (key) {
|
var nodes = Object.keys(this.collection(model)).map(function (key) {
|
||||||
return this.fromDb(model, this.collection(model)[key]);
|
return this.fromDb(model, this.collection(model)[key]);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -364,14 +402,7 @@ Memory.prototype.all = function all(model, filter, options, callback) {
|
||||||
var limit = filter.limit || nodes.length;
|
var limit = filter.limit || nodes.length;
|
||||||
nodes = nodes.slice(skip, skip + limit);
|
nodes = nodes.slice(skip, skip + limit);
|
||||||
}
|
}
|
||||||
|
return nodes;
|
||||||
process.nextTick(function () {
|
|
||||||
if (filter && filter.include) {
|
|
||||||
self._models[model].model.include(nodes, filter.include, options, callback);
|
|
||||||
} else {
|
|
||||||
callback(null, nodes);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function sorting(a, b) {
|
function sorting(a, b) {
|
||||||
var undefinedA, undefinedB;
|
var undefinedA, undefinedB;
|
||||||
|
@ -393,6 +424,19 @@ Memory.prototype.all = function all(model, filter, options, callback) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Memory.prototype.all = function all(model, filter, options, callback) {
|
||||||
|
var self = this;
|
||||||
|
var nodes = self._findAllSkippingIncludes(model, filter);
|
||||||
|
|
||||||
|
process.nextTick(function() {
|
||||||
|
if (filter && filter.include) {
|
||||||
|
self._models[model].model.include(nodes, filter.include, options, callback);
|
||||||
|
} else {
|
||||||
|
callback(null, nodes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
var where = filter.where;
|
var where = filter.where;
|
||||||
if (typeof where === 'function') {
|
if (typeof where === 'function') {
|
||||||
|
|
|
@ -345,7 +345,6 @@ describe('Memory connector', function() {
|
||||||
}
|
}
|
||||||
}, function (err, users) {
|
}, function (err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
console.log(users);
|
|
||||||
users.length.should.be.equal(5);
|
users.length.should.be.equal(5);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -695,6 +694,38 @@ describe('Memory connector', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('findOrCreate', function() {
|
||||||
|
var ds, Cars;
|
||||||
|
before(function() {
|
||||||
|
ds = new DataSource({connector: 'memory'});
|
||||||
|
Cars = ds.define('Cars', {
|
||||||
|
color: String
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a specific object once and in the subsequent calls it should find it', function(done) {
|
||||||
|
var creationNum = 0;
|
||||||
|
async.times(100, function(n, next) {
|
||||||
|
var initialData = {color: 'white'};
|
||||||
|
var query = {'where': initialData};
|
||||||
|
Cars.findOrCreate(query, initialData, function(err, car, created) {
|
||||||
|
if (created) creationNum++;
|
||||||
|
next(err, car);
|
||||||
|
});
|
||||||
|
}, function(err, cars) {
|
||||||
|
if (err) done(err);
|
||||||
|
Cars.find(function(err, data) {
|
||||||
|
if (err) done(err);
|
||||||
|
data.length.should.equal(1);
|
||||||
|
data[0].color.should.equal('white');
|
||||||
|
creationNum.should.equal(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('automigrate when NO models are attached', function() {
|
describe('automigrate when NO models are attached', function() {
|
||||||
var ds;
|
var ds;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
|
Loading…
Reference in New Issue