Skip to content
97 changes: 63 additions & 34 deletions lib/connectors/memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ function deserialize(dbObj) {
}
}

Memory.prototype.getCollection = function(model) {
var modelClass = this._models[model];
if (modelClass.settings.memory) {
model = modelClass.settings.memory.collection || model;
}
return model;
}

Memory.prototype.initCollection = function(model) {
this.collection(model, {});
this.collectionSeq(model, 1);
}

Memory.prototype.collection = function(model, val) {
model = this.getCollection(model);
if (arguments.length > 1) this.cache[model] = val;
return this.cache[model];
};

Memory.prototype.collectionSeq = function(model, val) {
model = this.getCollection(model);
if (arguments.length > 1) this.ids[model] = val;
return this.ids[model];
};

Memory.prototype.loadFromFile = function(callback) {
var self = this;
var hasLocalStorage = typeof window !== 'undefined' && window.localStorage;
Expand Down Expand Up @@ -161,36 +186,31 @@ Memory.prototype.saveToFile = function (result, callback) {
Memory.prototype.define = function defineModel(definition) {
this.constructor.super_.prototype.define.apply(this, [].slice.call(arguments));
var m = definition.model.modelName;
if(!this.cache[m]) {
this.cache[m] = {};
this.ids[m] = 1;
}
if(!this.collection(m)) this.initCollection(m);
};

Memory.prototype.create = function create(model, data, callback) {
// FIXME: [rfeng] We need to generate unique ids based on the id type
// FIXME: [rfeng] We don't support composite ids yet
var currentId = this.ids[model];
if (currentId === undefined) {
// First time
this.ids[model] = 1;
currentId = 1;
var currentId = this.collectionSeq(model);
if (currentId === undefined) { // First time
currentId = this.collectionSeq(model, 1);
}
var id = this.getIdValue(model, data) || currentId;
if (id > currentId) {
// If the id is passed in and the value is greater than the current id
currentId = id;
}
this.ids[model] = Number(currentId) + 1;
this.collectionSeq(model, Number(currentId) + 1);

var props = this._models[model].properties;
var idName = this.idName(model);
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
this.setIdValue(model, data, id);
if(!this.cache[model]) {
this.cache[model] = {};
if(!this.collection(model)) {
this.collection(model, {});
}
this.cache[model][id] = serialize(data);
this.collection(model)[id] = serialize(data);
this.saveToFile(id, callback);
};

Expand All @@ -210,30 +230,30 @@ Memory.prototype.updateOrCreate = function (model, data, callback) {

Memory.prototype.save = function save(model, data, callback) {
var id = this.getIdValue(model, data);
var cachedModels = this.cache[model];
var modelData = cachedModels && this.cache[model][id];
var cachedModels = this.collection(model);
var modelData = cachedModels && this.collection(model)[id];
modelData = modelData && deserialize(modelData);
if (modelData) {
data = merge(modelData, data);
}
this.cache[model][id] = serialize(data);
this.collection(model)[id] = serialize(data);
this.saveToFile(data, callback);
};

Memory.prototype.exists = function exists(model, id, callback) {
process.nextTick(function () {
callback(null, this.cache[model] && this.cache[model].hasOwnProperty(id));
callback(null, this.collection(model) && this.collection(model).hasOwnProperty(id));
}.bind(this));
};

Memory.prototype.find = function find(model, id, callback) {
process.nextTick(function () {
callback(null, id in this.cache[model] && this.fromDb(model, this.cache[model][id]));
callback(null, id in this.collection(model) && this.fromDb(model, this.collection(model)[id]));
}.bind(this));
};

Memory.prototype.destroy = function destroy(model, id, callback) {
delete this.cache[model][id];
delete this.collection(model)[id];
this.saveToFile(null, callback);
};

Expand Down Expand Up @@ -266,8 +286,8 @@ Memory.prototype.fromDb = function (model, data) {

Memory.prototype.all = function all(model, filter, callback) {
var self = this;
var nodes = Object.keys(this.cache[model]).map(function (key) {
return this.fromDb(model, this.cache[model][key]);
var nodes = Object.keys(this.collection(model)).map(function (key) {
return this.fromDb(model, this.collection(model)[key]);
}.bind(this));

if (filter) {
Expand Down Expand Up @@ -505,24 +525,23 @@ Memory.prototype.destroyAll = function destroyAll(model, where, callback) {
callback = where;
where = undefined;
}
var cache = this.cache[model];
var cache = this.collection(model);
var filter = null;
if (where) {
filter = applyFilter({where: where});
}
Object.keys(cache).forEach(function (id) {
if (!filter || filter(this.fromDb(model, cache[id]))) {
delete cache[id];
}
}.bind(this));
if (!where) {
this.cache[model] = {};
Object.keys(cache).forEach(function (id) {
if (!filter || filter(this.fromDb(model, cache[id]))) {
delete cache[id];
}
}.bind(this));
} else {
this.collection(model, {});
}
this.saveToFile(null, callback);
};

Memory.prototype.count = function count(model, callback, where) {
var cache = this.cache[model];
var cache = this.collection(model);
var data = Object.keys(cache);
if (where) {
var filter = {where: where};
Expand All @@ -539,7 +558,7 @@ Memory.prototype.count = function count(model, callback, where) {
Memory.prototype.update =
Memory.prototype.updateAll = function updateAll(model, where, data, cb) {
var self = this;
var cache = this.cache[model];
var cache = this.collection(model);
var filter = null;
where = where || {};
filter = applyFilter({where: where});
Expand Down Expand Up @@ -571,8 +590,8 @@ Memory.prototype.updateAttributes = function updateAttributes(model, id, data, c

this.setIdValue(model, data, id);

var cachedModels = this.cache[model];
var modelData = cachedModels && this.cache[model][id];
var cachedModels = this.collection(model);
var modelData = cachedModels && this.collection(model)[id];

if (modelData) {
this.save(model, data, cb);
Expand All @@ -594,6 +613,16 @@ Memory.prototype.buildNearFilter = function (filter) {
// noop
}

Memory.prototype.automigrate = function (models, cb) {
if (typeof models === 'function') cb = models, models = [];
if (models.length === 0) models = Object.keys(this._models);
var self = this;
models.forEach(function(m) {
self.initCollection(m);
});
if (cb) cb();
}

function merge(base, update) {
if (!base) {
return update;
Expand Down
Loading