Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

penseur

Package Overview
Dependencies
Maintainers
1
Versions
103
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

penseur - npm Package Compare versions

Comparing version 5.1.2 to 5.1.3

6

lib/modifier.js

@@ -32,4 +32,2 @@ 'use strict';

Hoek.assert(changes && typeof changes === 'object', 'Invalid changes object');
const without = [];

@@ -113,3 +111,5 @@ const wrapped = internals.wrap(changes, without, []);

if (!Object.keys(ref).length) {
if (!Object.keys(ref).length &&
!Array.isArray(ref)) {
return undefined;

@@ -116,0 +116,0 @@ }

@@ -120,6 +120,7 @@ 'use strict';

Hoek.assert(changes && typeof changes === 'object', 'Invalid changes object');
const diag = { id, changes };
const wrapped = Modifier.wrap(changes);
Unique.reserve(this, wrapped, id, (err, postUnique) => {
Unique.reserve(this, changes, id, (err, postUnique) => {

@@ -130,2 +131,3 @@ if (err) {

const wrapped = Modifier.wrap(changes);
const opts = { returnChanges: !!postUnique };

@@ -132,0 +134,0 @@ this._run(this._table.get(id)[typeof wrapped === 'object' ? 'update' : 'replace'](wrapped, opts), 'update', diag, callback, (ignore, result) => {

@@ -5,2 +5,3 @@ 'use strict';

const Boom = require('boom');
const Hoek = require('hoek');

@@ -52,21 +53,64 @@ const Items = require('items');

const fields = [];
const byHolder = (updateId ? [] : null);
[].concat(items).forEach((item) => {
// Find unique changes
table._unique.rules.forEach((rule) => {
const reserve = [];
const release = [];
items = [].concat(items);
for (let i = 0; i < items.length; ++i) {
const item = items[i];
for (let j = 0; j < table._unique.rules.length; ++j) {
const rule = table._unique.rules[j];
const values = internals.reach(item, rule.path);
if (values !== undefined) {
fields.push({ rule, values, id: updateId !== null ? updateId : item.id });
if (values.isBoom) {
return callback(values);
}
if (updateId) {
byHolder.push(rule);
if (values.length) {
reserve.push({ rule, values, id: updateId !== null ? updateId : item.id });
}
if (updateId &&
!values._bypass) {
release.push(rule);
}
}
});
}
}
// Prepare cleanup operation
const cleanup = (!release.length ? null : (changes, finalize) => {
const change = changes[0]; // Always includes one change
const eachRule = (rule, next) => {
let released = internals.reach(change.old_val, rule.path);
if (!released) {
return next();
}
const taken = internals.reach(change.new_val, rule.path);
if (taken) {
released = released.filter((value) => taken.indexOf(value) === -1);
}
if (!released.length) {
return next();
}
return rule.table.remove(released, next);
};
return Items.serial(release, eachRule, finalize);
});
if (!fields.length) {
return Hoek.nextTick(callback)();
// Reserve new values
if (!reserve.length) {
return Hoek.nextTick(callback)(null, cleanup);
}

@@ -82,33 +126,39 @@

const now = Date.now();
const reservations = [];
field.values.forEach((value) => {
// Try to get existing reservations
const rsv = { id: value, created: now };
rsv[field.rule.key] = field.id;
reservations.push(rsv);
});
let values = field.values;
field.rule.table.get(values, (err, existing) => {
field.rule.table.insert(reservations, next);
};
if (err) {
return next(err);
}
return Items.serial(fields, each, (err) => {
if (existing) {
const existingIds = [];
for (let i = 0; i < existing.length; ++i) {
const item = existing[i];
if (item[field.rule.key] !== field.id) {
return next(Boom.internal(`Action will violate unique restriction on ${item.id} in table ${field.rule.table.name}`));
}
if (err) {
return callback(err);
}
existingIds.push(item.id);
}
return callback(null, (changes, finalize) => {
values = values.filter((value) => existingIds.indexOf(value) === -1);
}
const change = changes[0]; // Always includes one change
const item = change.old_val;
const eachRule = (rule, next) => {
const reservations = [];
const now = Date.now();
values.forEach((value) => {
const oldValue = internals.reach(item, rule.path);
return rule.table.remove(oldValue, next);
};
const rsv = { id: value, created: now };
rsv[field.rule.key] = field.id;
reservations.push(rsv);
});
return Items.serial(byHolder, eachRule, finalize);
field.rule.table.insert(reservations, next);
});
});
};
Items.serial(reserve, each, (err) => callback(err, cleanup));
});

@@ -156,5 +206,41 @@ };

if (typeof ref === 'object') {
return Object.keys(ref);
const keys = Object.keys(ref);
let unset = false;
const taken = keys.filter((key) => {
if (typeof ref[key] !== 'function') {
return true;
}
if (ref[key].type !== 'unset') {
return true;
}
unset = true;
return false;
});
return taken.length ? taken : (unset ? [] : undefined);
}
if (typeof ref === 'function') {
if (ref.type === 'unset') {
return [];
}
if (ref.type === 'append') {
if (Array.isArray(ref.value) &&
ref.flags.single) {
return Boom.internal('Cannot add an array as single value to unique index value');
}
const result = Array.isArray(ref.value) ? ref.value : [ref.value];
result._bypass = true;
return result;
}
return Boom.internal('Cannot increment unique index value'); // type: increment
}
return [ref];

@@ -161,0 +247,0 @@ };

{
"name": "penseur",
"description": "Lightweight RethinkDB wrapper",
"version": "5.1.2",
"version": "5.1.3",
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)",

@@ -27,6 +27,6 @@ "repository": "git://github.com/hueniverse/penseur",

"scripts": {
"test": "lab -a code -t 100 -L -m 6000",
"test-cov-html": "lab -a code -r html -o coverage.html -m 6000"
"test": "lab -a code -t 100 -L -m 10000",
"test-cov-html": "lab -a code -r html -o coverage.html -m 10000"
},
"license": "BSD-3-Clause"
}

@@ -74,2 +74,22 @@ 'use strict';

it('returns the requested objects (array of one)', (done) => {
const db = new Penseur.Db('penseurtest');
db.establish(['test'], (err) => {
expect(err).to.not.exist();
db.test.insert([{ id: 1, a: 1 }, { id: 2, a: 2 }, { id: 3, a: 1 }], (err, keys) => {
expect(err).to.not.exist();
db.test.get([1], (err, result) => {
expect(err).to.not.exist();
expect(result).to.deep.equal([{ id: 1, a: 1 }]);
done();
});
});
});
});
it('returns the requested objects found (partial)', (done) => {

@@ -653,2 +673,20 @@

});
it('errors on key conflict', (done) => {
const db = new Penseur.Db('penseurtest');
db.establish(['test'], (err) => {
expect(err).to.not.exist();
db.test.insert({ id: 1, a: 1 }, (err, key1) => {
expect(err).to.not.exist();
db.test.insert({ id: 1, a: 1 }, (err, key2) => {
expect(err).to.exist();
done();
});
});
});
});
});

@@ -655,0 +693,0 @@

@@ -70,3 +70,3 @@ 'use strict';

expect(err).to.not.exist();
db.test.insert([{ id: 1, a: { b: 1 } }, { id: 2, a: { c: { d: 2 } } }], (err, keys) => {
db.test.insert([{ id: 1, a: { b: 1 } }, { id: 2, a: { c: { d: [2] } } }], (err, keys) => {

@@ -79,3 +79,8 @@ expect(err).to.not.exist();

expect(err).to.exist();
done();
db.test.update(2, { a: { c: { d: db.append([1, 2]) } } }, (err) => {
expect(err).to.not.exist();
done();
});
});

@@ -118,2 +123,118 @@ });

it('allows appending a unique value', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: '1', a: [1] }, (err, key) => {
expect(err).to.not.exist();
db.test.update('1', { a: db.append(2) }, (err) => {
expect(err).to.not.exist();
db.test.update('1', { a: db.append(1) }, (err) => {
expect(err).to.not.exist();
done();
});
});
});
});
});
it('releases value on unset', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: '1', a: 1 }, (err, key) => {
expect(err).to.not.exist();
db.test.update('1', { a: db.unset() }, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: 2, a: 1 }, (err) => {
expect(err).to.not.exist();
done();
});
});
});
});
});
it('ignores empty object', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: '1', a: {} }, (err, key) => {
expect(err).to.not.exist();
done();
});
});
});
it('allows adding a unique value via update', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: '1' }, (err, key) => {
expect(err).to.not.exist();
db.test.update('1', { a: 2 }, (err) => {
expect(err).to.not.exist();
done();
});
});
});
});
it('forbids violating a unique value', (done) => {

@@ -159,14 +280,82 @@

expect(err).to.not.exist();
db.test.insert({ a: { b: 1 } }, (err, key1) => {
db.test.insert({ a: { b: [1] } }, (err, key1) => {
expect(err).to.not.exist();
db.test.insert({ a: { c: 2, d: 4 } }, (err, key2) => {
db.test.update(key1, { a: { b: db.append(2) } }, (err) => {
expect(err).to.not.exist();
db.test.insert({ a: { b: 3 } }, (err, key3) => {
db.test.insert({ a: { c: 2, d: 4 } }, (err, key2) => {
expect(err).to.exist();
db.test.insert({ a: { d: 5 } }, (err, key4) => {
expect(err).to.not.exist();
db.test.insert({ a: { b: 3 } }, (err, key3) => {
expect(err).to.exist();
db.test.insert({ a: { d: 5 } }, (err, key4) => {
expect(err).to.exist();
done();
});
});
});
});
});
});
});
it('allows same owner changes', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: 1, a: { c: 1 } }, (err, key1) => {
expect(err).to.not.exist();
db.test.update(1, { a: { c: 5 } }, (err) => {
expect(err).to.not.exist();
done();
});
});
});
});
it('releases reservations on update (keys)', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ id: 1, a: { b: 1 } }, (err, key1) => {
expect(err).to.not.exist();
db.test.insert({ id: 2, a: { c: 2, d: 4 } }, (err, key2) => {
expect(err).to.not.exist();
db.test.update(2, { a: { c: db.unset() } }, (err) => {
expect(err).to.not.exist();
db.test.update(1, { a: { c: 5 } }, (err) => {
expect(err).to.not.exist();
done();

@@ -208,3 +397,11 @@ });

expect(err).to.exist();
done();
db.test.update(key2, { a: [] }, (err) => {
expect(err).to.not.exist();
db.test.insert({ a: ['a'] }, (err, key5) => {
expect(err).to.not.exist();
done();
});
});
});

@@ -217,3 +414,3 @@ });

it('cusomizes unique table name', (done) => {
it('customizes unique table name', (done) => {

@@ -322,2 +519,83 @@ const db = new Penseur.Db('penseurtest');

});
it('errors on incrementing unique index', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ a: 1 }, (err, key) => {
expect(err).to.not.exist();
db.test.update(key, { a: db.increment(1) }, (err) => {
expect(err).to.exist();
done();
});
});
});
});
it('errors on appending a single array to a unique index', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test.insert({ a: [1] }, (err, key) => {
expect(err).to.not.exist();
db.test.update(key, { a: db.append([2], { single: true }) }, (err) => {
expect(err).to.exist();
done();
});
});
});
});
it('errors on database unique table get error', (done) => {
const db = new Penseur.Db('penseurtest');
const settings = {
penseur_unique_test_a: true, // Test cleanup
test: {
id: 'uuid',
unique: {
path: 'a'
}
}
};
db.establish(settings, (err) => {
expect(err).to.not.exist();
db.test._unique.rules[0].table.get = (id, callback) => callback(new Error('boom'));
db.test.insert([{ a: 1 }, { a: 2 }], (err, keys) => {
expect(err).to.exist();
done();
});
});
});
});

@@ -324,0 +602,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc