Socket
Socket
Sign inDemoInstall

camo

Package Overview
Dependencies
125
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.1 to 0.3.0

6

CHANGELOG.md

@@ -0,1 +1,7 @@

## 0.3.0 (2015-06-18)
Features:
- Added support for MongoDB using [node-mongodb-native](https://www.npmjs.com/package/mongodb) as the backend.
- Added `.toCanonicalId()` and `.isNativeId()` to `DatabaseClient` and its child classes.
## 0.2.1 (2015-06-17)

@@ -2,0 +8,0 @@

@@ -52,2 +52,10 @@ "use strict";

toCanonicalId(id) {
throw new TypeError('You must override toCanonicalId.');
}
isNativeId(value) {
throw new TypeError('You must override isNativeId.');
}
driver() {

@@ -54,0 +62,0 @@ throw new TypeError('You must override driver.');

165

lib/clients/mongoclient.js

@@ -5,54 +5,161 @@ "use strict";

var fs = require('fs');
var _ = require('lodash');
var MDBClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectId;
var DatabaseClient = require('./client');
var MDBClient = require('mongodb').MongoClient;
class MongoClient extends DatabaseClient {
constructor(url, mongo) {
super(url);
constructor(url, mongo) {
super(url);
this._mongo = mongo;
}
this._mongo = mongo;
}
save(collection, query, values) {
// Mongo
// Use updateOne
save(collection, id, values) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
// TODO: I'd like to just use update with upsert:true, but I'm
// note sure how the query will work if id == null. Seemed to
// have some problems before with passing null ids.
if (id === null) {
db.insertOne(values, function(error, result) {
if (error) return reject(error);
if (!result.hasOwnProperty('insertedId') || result.insertedId === null) {
return reject(new Error('Save failed to generate ID for object.'));
}
return resolve(result.insertedId);
});
} else {
db.updateOne({ _id: id }, { $set: values }, function(error, result) {
if (error) return reject(error);
return resolve();
});
}
});
}
delete(collection) {
// Mongo
// Use deleteOne
delete(collection, id) {
var that = this;
return new Promise(function(resolve, reject) {
if (id === null) resolve(0);
var db = that._mongo.collection(collection);
db.deleteOne({ _id: id }, {w:1}, function (error, result) {
if (error) return reject(error);
return resolve(result.deletedCount);
});
});
}
static deleteOne(collection, query) {
// Mongo
// Use deleteOne
deleteOne(collection, query) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
db.deleteOne(query, {w:1}, function (error, result) {
if (error) return reject(error);
return resolve(result.deletedCount);
});
});
}
static deleteMany(collection, query) {
// Mongo
// Use deleteMany
deleteMany(collection, query) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
db.deleteMany(query, {w:1}, function (error, result) {
if (error) return reject(error);
return resolve(result.deletedCount);
});
});
}
static loadOne(collection, query) {
// Use findOne
loadOne(collection, query) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
db.findOne(query, function (error, doc) {
if (error) return reject(error);
return resolve(doc);
});
});
}
static loadMany(collection, query) {
// Use find
loadMany(collection, query) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
db.find(query).toArray(function (error, docs) {
if (error) return reject(error);
return resolve(docs);
});
});
}
count(collection, query) {
var that = this;
return new Promise(function(resolve, reject) {
var db = that._mongo.collection(collection);
db.count(query, function (error, count) {
if (error) return reject(error);
return resolve(count);
});
});
}
static connect(url) {
return new Promise(function(resolve, reject) {
MDBClient.connect(url, function(error, client) {
if (error) return reject(error);
return resolve(new MongoClient(url, client));
});
});
}
return new Promise(function(resolve, reject) {
MDBClient.connect(url, function(error, client) {
if (error) return reject(error);
return resolve(new MongoClient(url, client));
});
});
}
close() {
return this._mongo.close();
var that = this;
return new Promise(function(resolve, reject) {
that._mongo.close(function(error) {
if (error) return reject(error);
return resolve();
});
});
}
clearCollection(collection) {
var that = this;
return new Promise(function(resolve, reject) {
that._mongo.dropCollection(collection, function(error, result) {
if (error) return reject(error);
return resolve();
});
});
}
dropDatabase() {
var that = this;
return new Promise(function(resolve, reject) {
that._mongo.dropDatabase(function(error, result) {
if (error) return reject(error);
return resolve();
});
});
}
toCanonicalId(id) {
return id.toString();
}
isNativeId(value) {
return value instanceof ObjectId;
}
driver() {
return this._mongo;
}
}
module.exports = MongoClient;

@@ -58,3 +58,4 @@ "use strict";

if (error) return reject(error);
return resolve(result);
return resolve(result._id);
});

@@ -145,2 +146,4 @@ } else {

// TODO: Load all data upfront or on-demand?
// Maybe give user the option to load upfront.
// But which should we do by default?
/*fs.readdir(dbFolderPath, function(error, files) {

@@ -158,4 +161,4 @@ files.forEach(function(file) {

});*/
global.CLIENT = new NeDbClient(dbFolderPath, collections);
resolve(global.CLIENT);
//global.CLIENT = new NeDbClient(dbFolderPath, collections);
resolve(new NeDbClient(dbFolderPath, collections));
});

@@ -199,2 +202,11 @@ }

toCanonicalId(id) {
return id;
}
// Native ids are the same as NeDB ids
isNativeId(value) {
return true;
}
driver() {

@@ -201,0 +213,0 @@ return this._collections;

19

lib/db.js
var NeDbClient = require('./clients/nedbclient');
var MongoClient = require('mongodb').MongoClient;
var MongoClient = require('./clients/mongoclient');
var database = null;
exports.database = database;
exports.connect = function(url) {

@@ -12,3 +8,3 @@ if (url.indexOf('nedb://') > -1) {

return NeDbClient.connect(url).then(function(db) {
database = db;
global.CLIENT = db;
return db;

@@ -18,10 +14,5 @@ });

// url example: 'mongodb://localhost:27017/myproject'
return new Promise(function(resolve, reject) {
MongoClient.connect(url, function(error, db) {
if (error) {
return reject(error);
}
database = db;
resolve(db);
});
return MongoClient.connect(url).then(function(db) {
global.CLIENT = db;
return db;
});

@@ -28,0 +19,0 @@ } else {

@@ -81,3 +81,3 @@ "use strict";

this._schema = { // Defines document structure/properties
_id: { type: String }
_id: { type: String }, // Native ID to backend database
};

@@ -239,5 +239,7 @@ this._values = {}; // Contains values for properties defined in schema

}).then(function(data) {
// TODO: Need to return this so if its a promise it'll work
that.postValidate();
return data;
}).then(function(data) {
// TODO: Need to return this so if its a promise it'll work
that.preSave();

@@ -247,9 +249,9 @@ return data;

return DB().save(that._meta.collection, that.id, data);
}).then(function(data) {
that.postSave();
return data;
}).then(function(data) {
}).then(function(id) {
if (that.id === null) {
that.id = data._id;
that.id = id;
}
}).then(function() {
return that.postSave();
}).then(function() {
return that;

@@ -419,3 +421,5 @@ }).catch(function(error) {

}
else if (isString(anInstance[key]) && isModel(anInstance._schema[key].type)) {
// Handle anInstance[key] being a string id, a native id, or a Document instance
else if ((isString(anInstance[key]) || DB().isNativeId(anInstance[key])) &&
isModel(anInstance._schema[key].type)) {
keys.push(key);

@@ -439,3 +443,3 @@ }

documents.forEach(function(d) {
ids[k][d.id] = [].concat(d[k]); // Handles values and arrays
ids[k][DB().toCanonicalId(d.id)] = [].concat(d[k]); // Handles values and arrays

@@ -455,6 +459,8 @@ // Also, initialize document member arrays

_.keys(ids[key]).forEach(function(k) {
// Before adding to list, we convert id to the
// backend database's native ID format.
keyIds = keyIds.concat(ids[key][k]);
});
// Handle array of references (ex: [MyObject])
// Handle array of references (like [MyObject])
var type = null;

@@ -467,3 +473,3 @@ if (isArray(anInstance._schema[key].type)) {

// Bulk load objects
// Bulk load dereferences
var p = type.loadMany({ '_id': { $in: keyIds } }, { populate: false })

@@ -476,7 +482,13 @@ .then(function(dereferences) {

// ...if this dereference is in the array...
if (ids[key][k].indexOf(deref.id) > -1) {
var cIds = [];
ids[key][k].forEach(function(i) {
cIds.push(DB().toCanonicalId(i));
});
if (cIds.indexOf(DB().toCanonicalId(deref.id)) > -1) {
// ...find the document it belongs to...
documents.forEach(function(doc) {
// ...and make the assignment (value or array-based).
if (doc.id === k) {
if (DB().toCanonicalId(doc.id) === k) {
if (isArray(anInstance._schema[key].type)) {

@@ -483,0 +495,0 @@ doc[key].push(deref);

{
"name" : "camo",
"version" : "0.2.1",
"version" : "0.3.0",
"description" : "A lightweight ES6 ODM for Mongo-like databases.",

@@ -5,0 +5,0 @@ "author": {

@@ -16,2 +16,3 @@ "use strict";

var url = 'nedb://' + __dirname + '/nedbdata';
//var url = 'mongodb://localhost/camo_test';
var database = null;

@@ -22,3 +23,3 @@

database = db;
return database.clearCollection('data');
return database.dropDatabase();
}).then(function() {

@@ -34,13 +35,7 @@ return done();

afterEach(function(done) {
database.clearCollection('data').then(function() {
database.driver().data.persistence.compactDatafile();
}).then(done, done);
database.dropDatabase().then(function() {}).then(done, done);
});
after(function(done) {
database.dropDatabase().then(function() {
_.keys(database.driver()).forEach(function(key) {
database.driver()[key].persistence.compactDatafile();
});
}).then(done, done);
database.dropDatabase().then(function() {}).then(done, done);
});

@@ -53,5 +48,5 @@

data.save().then(function(d) {
validateId(d);
validateData1(d);
data.save().then(function() {
validateId(data);
validateData1(data);
}).then(done, done);

@@ -66,4 +61,4 @@ });

data.save().then(function(d) {
validateId(d);
data.save().then(function() {
validateId(data);
return Data.loadOne({item:99});

@@ -83,5 +78,5 @@ }).then(function(d) {

Promise.all([data1.save(), data2.save()]).then(function(datas) {
validateId(datas[0]);
validateId(datas[1]);
Promise.all([data1.save(), data2.save()]).then(function() {
validateId(data1);
validateId(data2);
return Data.loadMany({});

@@ -110,5 +105,5 @@ }).then(function(datas) {

Promise.all([data1.save(), data2.save()]).then(function(datas) {
validateId(datas[0]);
validateId(datas[1]);
Promise.all([data1.save(), data2.save()]).then(function() {
validateId(data1);
validateId(data2);
return Data.count({ number: 3 });

@@ -125,5 +120,5 @@ }).then(function(count) {

Promise.all([data1.save(), data2.save()]).then(function(datas) {
validateId(datas[0]);
validateId(datas[1]);
Promise.all([data1.save(), data2.save()]).then(function() {
validateId(data1);
validateId(data2);
return Data.count({});

@@ -141,5 +136,5 @@ }).then(function(count) {

data.save().then(function(d) {
validateId(d);
return d.delete();
data.save().then(function() {
validateId(data);
return data.delete();
}).then(function(numDeleted) {

@@ -159,4 +154,4 @@ expect(numDeleted).to.be.equal(1);

data.save().then(function(d) {
validateId(d);
data.save().then(function() {
validateId(data);
return Data.deleteOne({number: 1});

@@ -178,5 +173,5 @@ }).then(function(numDeleted) {

Promise.all([data1.save(), data2.save()]).then(function(datas) {
validateId(datas[0]);
validateId(datas[1]);
Promise.all([data1.save(), data2.save()]).then(function() {
validateId(data1);
validateId(data2);
return Data.deleteMany({});

@@ -198,5 +193,5 @@ }).then(function(numDeleted) {

Promise.all([data1.save(), data2.save()]).then(function(datas) {
validateId(datas[0]);
validateId(datas[1]);
Promise.all([data1.save(), data2.save()]).then(function() {
validateId(data1);
validateId(data2);
return Data.clearCollection();

@@ -203,0 +198,0 @@ }).then(function() {

@@ -8,2 +8,3 @@ "use strict";

var Document = require('../index').Document;
var isModel = require('../lib/validate').isModel;
var Data = require('./data');

@@ -18,2 +19,3 @@ var getData1 = require('./util').data1;

var url = 'nedb://' + __dirname + '/nedbdata';
//var url = 'mongodb://localhost/camo_test';
var database = null;

@@ -65,7 +67,7 @@

data.ref.save().then(function(d) {
validateId(d);
data.ref.save().then(function() {
validateId(data.ref);
return data.save();
}).then(function(d) {
validateId(d);
}).then(function() {
validateId(data);
return ReferencerModel.loadOne({ num: 1 });

@@ -104,10 +106,10 @@ }).then(function(d) {

data.refs[0].save().then(function(d) {
validateId(d);
data.refs[0].save().then(function() {
validateId(data.refs[0]);
return data.refs[1].save();
}).then(function(d) {
validateId(d);
}).then(function() {
validateId(data.refs[1]);
return data.save();
}).then(function(d) {
validateId(d);
}).then(function() {
validateId(data);
return ReferencerModel.loadOne({ num: 1 });

@@ -151,9 +153,9 @@ }).then(function(d) {

boss.save().then(function(b) {
validateId(b);
boss.save().then(function() {
validateId(boss);
return employee.save();
}).then(function(e) {
validateId(e);
validateId(e.boss);
}).then(function() {
validateId(employee);
validateId(employee.boss);

@@ -163,6 +165,6 @@ boss.employees.push(employee);

return boss.save();
}).then(function(b) {
validateId(b);
validateId(b.employees[0]);
validateId(b.employees[0].boss);
}).then(function() {
validateId(boss);
validateId(boss.employees[0]);
validateId(boss.employees[0].boss);

@@ -184,3 +186,4 @@ return Boss.loadOne({ salary: 10000000 });

// to the employee is still the ID.
expect(b.employees[0].boss).to.be.a('string');
expect(b.employees[0].boss).to.not.be.null;
expect(!isModel(b.employees[0].boss)).to.be.true;
}).then(done, done);

@@ -201,5 +204,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.str).to.be.equal('hello');
data.save().then(function() {
validateId(data);
expect(data.str).to.be.equal('hello');
}).then(done, done);

@@ -220,5 +223,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.num).to.be.equal(26);
data.save().then(function() {
validateId(data);
expect(data.num).to.be.equal(26);
}).then(done, done);

@@ -239,5 +242,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.bool).to.be.equal(true);
data.save().then(function() {
validateId(data);
expect(data.bool).to.be.equal(true);
}).then(done, done);

@@ -259,5 +262,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.date).to.be.equal(date);
data.save().then(function() {
validateId(data);
expect(data.date).to.be.equal(date);
}).then(done, done);

@@ -278,6 +281,6 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.obj.hi).to.not.be.null;
expect(d.obj.hi).to.be.equal('bye');
data.save().then(function() {
validateId(data);
expect(data.obj.hi).to.not.be.null;
expect(data.obj.hi).to.be.equal('bye');
}).then(done, done);

@@ -298,5 +301,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.buf.toString('ascii')).to.be.equal('hello');
data.save().then(function() {
validateId(data);
expect(data.buf.toString('ascii')).to.be.equal('hello');
}).then(done, done);

@@ -317,8 +320,8 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.arr).to.have.length(3);
expect(d.arr).to.include(1);
expect(d.arr).to.include('number');
expect(d.arr).to.include(true);
data.save().then(function() {
validateId(data);
expect(data.arr).to.have.length(3);
expect(data.arr).to.include(1);
expect(data.arr).to.include('number');
expect(data.arr).to.include(true);
}).then(done, done);

@@ -339,8 +342,8 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.arr).to.have.length(3);
expect(d.arr).to.include('1');
expect(d.arr).to.include('2');
expect(d.arr).to.include('3');
data.save().then(function() {
validateId(data);
expect(data.arr).to.have.length(3);
expect(data.arr).to.include('1');
expect(data.arr).to.include('2');
expect(data.arr).to.include('3');
}).then(done, done);

@@ -361,3 +364,3 @@ });

data.save().then(function(d) {
data.save().then(function() {
expect.fail(null, Error, 'Expected error, but got none.');

@@ -381,3 +384,3 @@ }).catch(function(error) {

data.save().then(function(d) {
data.save().then(function() {
expect.fail(null, Error, 'Expected error, but got none.');

@@ -395,5 +398,5 @@ }).catch(function(error) {

data.save().then(function(d) {
validateId(d);
expect(d.source).to.be.equal('reddit');
data.save().then(function() {
validateId(data);
expect(data.source).to.be.equal('reddit');
}).then(done, done);

@@ -406,5 +409,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.date).to.be.lessThan(Date.now());
data.save().then(function() {
validateId(data);
expect(data.date).to.be.lessThan(Date.now());
}).then(done, done);

@@ -420,5 +423,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.source).to.be.equal('wired');
data.save().then(function() {
validateId(data);
expect(data.source).to.be.equal('wired');
}).then(done, done);

@@ -432,3 +435,3 @@ });

data.save().then(function(d) {
data.save().then(function() {
expect.fail(null, Error, 'Expected error, but got none.');

@@ -447,5 +450,5 @@ }).catch(function(error) {

data.save().then(function(d) {
validateId(d);
expect(d.item).to.be.equal(1);
data.save().then(function() {
validateId(data);
expect(data.item).to.be.equal(1);
}).then(done, done);

@@ -459,5 +462,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.item).to.be.equal(0);
data.save().then(function() {
validateId(data);
expect(data.item).to.be.equal(0);
}).then(done, done);

@@ -471,3 +474,3 @@ });

data.save().then(function(d) {
data.save().then(function() {
expect.fail(null, Error, 'Expected error, but got none.');

@@ -486,5 +489,5 @@ }).catch(function(error) {

data.save().then(function(d) {
validateId(d);
expect(d.item).to.be.equal(99);
data.save().then(function() {
validateId(data);
expect(data.item).to.be.equal(99);
}).then(done, done);

@@ -498,5 +501,5 @@ });

data.save().then(function(d) {
validateId(d);
expect(d.item).to.be.equal(100);
data.save().then(function() {
validateId(data);
expect(data.item).to.be.equal(100);
}).then(done, done);

@@ -510,3 +513,3 @@ });

data.save().then(function(d) {
data.save().then(function() {
expect.fail(null, Error, 'Expected error, but got none.');

@@ -562,4 +565,4 @@ }).catch(function(error) {

person.save().then(function(p) {
validateId(p);
person.save().then(function() {
validateId(person);

@@ -577,3 +580,5 @@ // Pre/post save and validate should be called

return person.delete();
}).then(function() {
}).then(function(numDeleted) {
expect(numDeleted).to.be.equal(1);
expect(preDeleteCalled).to.be.equal(true);

@@ -580,0 +585,0 @@ expect(postDeleteCalled).to.be.equal(true);

@@ -7,4 +7,4 @@ var expect = require('chai').expect;

expect(obj).to.be.a('object');
expect(obj.id).to.be.a('string');
expect(obj.id).to.have.length.of.at.least(1);
expect(obj.id.toString()).to.be.a('string');
expect(obj.id.toString()).to.have.length.of.at.least(1);
};

@@ -11,0 +11,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc