Comparing version 8.0.0 to 8.0.1
@@ -416,3 +416,3 @@ 'use strict'; | ||
run(request, options = {}) { | ||
async run(request, options = {}) { | ||
@@ -431,9 +431,16 @@ // Extract table name from ReQL object | ||
return this._run(request, options, table, 'run'); | ||
const track = { table, action: 'run' }; | ||
try { | ||
return await this._run(request, track, options); | ||
} | ||
catch (err) { | ||
throw Table.error(err, track); | ||
} | ||
} | ||
async _run(request, options, table, action, inputs = null) { | ||
async _run(request, track, options) { | ||
if (!this._connection) { | ||
throw Table._error(table, action, 'Database disconnected', inputs); | ||
throw new Error('Database disconnected'); | ||
} | ||
@@ -444,38 +451,29 @@ | ||
const { table, action, inputs = null } = track; | ||
this._settings.test[table] = this._settings.test[table] || []; | ||
const track = { action }; | ||
if (inputs !== null) { | ||
track.inputs = inputs; | ||
} | ||
this._settings.test[table].push({ action, inputs }); | ||
} | ||
this._settings.test[table].push(track); | ||
const result = await request.run(this._connection, options); | ||
if (result === null) { | ||
return null; | ||
} | ||
try { | ||
const result = await request.run(this._connection, options); | ||
if (result === null) { | ||
return null; | ||
} | ||
if (result.errors) { | ||
throw new Error(result.first_error); | ||
} | ||
if (result.errors) { | ||
throw Table._error(table, action, result.first_error, inputs); | ||
} | ||
// Single item | ||
// Single item | ||
if (typeof result.toArray !== 'function' || | ||
Array.isArray(result)) { | ||
if (typeof result.toArray !== 'function' || | ||
Array.isArray(result)) { | ||
return internals.empty(result); | ||
} | ||
return internals.empty(result); | ||
} | ||
// Cursor | ||
// Cursor | ||
const results = await result.toArray(); | ||
result.close(); | ||
return internals.empty(results); | ||
} | ||
catch (err) { | ||
throw Table._error(table, action, err, inputs); | ||
} | ||
const results = await result.toArray(); | ||
result.close(); | ||
return internals.empty(results); | ||
} | ||
@@ -482,0 +480,0 @@ |
387
lib/table.js
@@ -29,3 +29,3 @@ 'use strict'; | ||
exports = module.exports = class { | ||
exports = module.exports = internals.Table = class { | ||
@@ -44,16 +44,15 @@ constructor(name, db, options) { | ||
get(ids, options = {}) { | ||
async get(ids, options = {}) { | ||
const diag = { ids, options }; | ||
const track = { table: this.name, action: 'get', inputs: { ids, options } }; | ||
const batch = Array.isArray(ids); | ||
try { | ||
const batch = Array.isArray(ids); | ||
ids = Id.normalize(ids, true); | ||
const query = (batch ? this.raw.getAll(RethinkDB.args(ids)) : this.raw.get(ids)); | ||
return await this._db._run(this._refine(query, options), track); | ||
} | ||
catch (err) { | ||
return Promise.reject(this._error('get', err.message, diag)); | ||
throw internals.Table.error(err, track); | ||
} | ||
const query = (batch ? this.raw.getAll(RethinkDB.args(ids)) : this.raw.get(ids)); | ||
return this._run(this._refine(query, options), 'get', diag); | ||
} | ||
@@ -89,18 +88,25 @@ | ||
all(options = {}) { | ||
async all(options = {}) { | ||
return this._run(this._refine(this.raw, options, true), 'all'); | ||
const track = { table: this.name, action: 'all' }; | ||
try { | ||
return await this._db._run(this._refine(this.raw, options, true), track); | ||
} | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
exist(id) { | ||
async exist(id) { | ||
const diag = { id }; | ||
const track = { table: this.name, action: 'exist', inputs: { id } }; | ||
try { | ||
id = Id.normalize(id, false); | ||
return await this._db._run(this.raw.get(id).ne(null), track); | ||
} | ||
catch (err) { | ||
return Promise.reject(this._error('exist', err.message, diag)); | ||
throw internals.Table.error(err, track); | ||
} | ||
return this._run(this.raw.get(id).ne(null), 'exist', diag); | ||
} | ||
@@ -117,20 +123,33 @@ | ||
const selection = Criteria.select(criteria, this).pluck(fields).distinct(); | ||
const result = await this._run(selection, 'distinct', { criteria, fields }); | ||
if (!result) { | ||
return null; | ||
} | ||
const track = { table: this.name, action: 'distinct', inputs: { criteria, fields } }; | ||
if (fields.length === 1) { | ||
return result.map((item) => item[fields[0]]); | ||
try { | ||
const selection = Criteria.select(criteria, this).pluck(fields).distinct(); | ||
const result = await this._db._run(selection, track); | ||
if (!result) { | ||
return null; | ||
} | ||
if (fields.length === 1) { | ||
return result.map((item) => item[fields[0]]); | ||
} | ||
return result; | ||
} | ||
return result; | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
query(criteria, options = {}) { | ||
async query(criteria, options = {}) { | ||
const diag = { criteria, options }; | ||
const selection = Criteria.select(criteria, this); | ||
return this._run(this._refine(selection, options), 'query', diag); | ||
const track = { table: this.name, action: 'query', inputs: { criteria, options } }; | ||
try { | ||
const selection = Criteria.select(criteria, this); | ||
return await this._db._run(this._refine(selection, options), track); | ||
} | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -140,18 +159,31 @@ | ||
const diag = { criteria }; | ||
const result = await this._run(Criteria.select(criteria, this), 'single', diag); | ||
if (!result) { | ||
return null; | ||
} | ||
const track = { table: this.name, action: 'single', inputs: { criteria } }; | ||
if (result.length !== 1) { | ||
return Promise.reject(this._error('single', 'Found multiple items', diag)); | ||
try { | ||
const result = await this._db._run(Criteria.select(criteria, this), track); | ||
if (!result) { | ||
return null; | ||
} | ||
if (result.length !== 1) { | ||
throw new Error('Found multiple items'); | ||
} | ||
return result[0]; | ||
} | ||
return result[0]; | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
count(criteria) { | ||
async count(criteria) { | ||
return this._run(Criteria.select(criteria, this).count(), 'count', { criteria }); | ||
const track = { table: this.name, action: 'count', inputs: { criteria } }; | ||
try { | ||
return await this._db._run(Criteria.select(criteria, this).count(), track); | ||
} | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -191,53 +223,49 @@ | ||
const diag = { items, options }; | ||
const track = { table: this.name, action: 'insert', inputs: { items, options } }; | ||
let wrapped; | ||
let postUnique; | ||
try { | ||
wrapped = await Id.wrap(this, items); | ||
postUnique = await Unique.reserve(this, wrapped, options.merge === true); | ||
} | ||
catch (err) { | ||
throw this._error('insert', err, diag); | ||
} | ||
const wrapped = await Id.wrap(this, items); | ||
const postUnique = await Unique.reserve(this, wrapped, options.merge === true); | ||
const opt = { | ||
conflict: options.merge ? 'update' : 'error', | ||
returnChanges: !!postUnique | ||
}; | ||
const opt = { | ||
conflict: options.merge ? 'update' : 'error', | ||
returnChanges: !!postUnique | ||
}; | ||
const result = await this._run(this.raw.insert(wrapped, opt), 'insert', diag); | ||
if (postUnique) { | ||
await postUnique(result.changes); | ||
} | ||
const result = await this._db._run(this.raw.insert(wrapped, opt), track); | ||
if (postUnique) { | ||
await postUnique(result.changes); | ||
} | ||
// Single item | ||
// Single item | ||
if (!Array.isArray(wrapped)) { | ||
return (wrapped[this.primary] !== undefined ? wrapped[this.primary] : result.generated_keys[0]); | ||
} | ||
if (!Array.isArray(wrapped)) { | ||
return (wrapped[this.primary] !== undefined ? wrapped[this.primary] : result.generated_keys[0]); | ||
} | ||
// Items array | ||
// Items array | ||
const generated = result.generated_keys || []; | ||
if (generated.length === wrapped.length) { | ||
return result.generated_keys; | ||
} | ||
const generated = result.generated_keys || []; | ||
if (generated.length === wrapped.length) { | ||
return result.generated_keys; | ||
} | ||
// Mixed array | ||
// Mixed array | ||
const ids = []; | ||
let g = 0; | ||
for (let i = 0; i < wrapped.length; ++i) { | ||
if (wrapped[i][this.primary] !== undefined) { | ||
ids.push(wrapped[i][this.primary]); | ||
const ids = []; | ||
let g = 0; | ||
for (let i = 0; i < wrapped.length; ++i) { | ||
if (wrapped[i][this.primary] !== undefined) { | ||
ids.push(wrapped[i][this.primary]); | ||
} | ||
else { | ||
ids.push(result.generated_keys[g++]); | ||
} | ||
} | ||
else { | ||
ids.push(result.generated_keys[g++]); | ||
} | ||
return ids; | ||
} | ||
return ids; | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -247,3 +275,3 @@ | ||
const diag = { ids, changes }; | ||
const track = { table: this.name, action: 'update', inputs: { ids, changes } }; | ||
@@ -276,3 +304,3 @@ if (Array.isArray(ids)) { | ||
const batch = batches[i]; | ||
await this._update(batch.map((item) => item.id), batch, diag); | ||
await this._update(batch.map((item) => item.id), batch, track); | ||
} | ||
@@ -294,32 +322,24 @@ | ||
return this._update(ids, changes, diag); | ||
return this._update(ids, changes, track); | ||
} | ||
async _update(ids, changes, diag) { | ||
async _update(ids, changes, track) { | ||
const batch = Array.isArray(ids); | ||
try { | ||
const batch = Array.isArray(ids); | ||
ids = Id.normalize(ids, true); | ||
} | ||
catch (err) { | ||
throw this._error('update', err.message, diag); | ||
} | ||
let postUnique; | ||
try { | ||
postUnique = await Unique.reserve(this, changes, (batch ? true : ids)); | ||
const postUnique = await Unique.reserve(this, changes, (batch ? true : ids)); | ||
const wrapped = Modifier.wrap(changes, this); | ||
const opts = { returnChanges: !!postUnique }; | ||
const query = (batch ? this.raw.getAll(RethinkDB.args(ids)) : this.raw.get(ids)); | ||
const result = await this._db._run(query.replace(wrapped, opts), track); | ||
if (postUnique) { | ||
return postUnique(result.changes); | ||
} | ||
} | ||
catch (err) { | ||
throw this._error('update', err, diag); | ||
throw internals.Table.error(err, track); | ||
} | ||
const wrapped = Modifier.wrap(changes, this); | ||
const opts = { returnChanges: !!postUnique }; | ||
const query = (batch ? this.raw.getAll(RethinkDB.args(ids)) : this.raw.get(ids)); | ||
const result = await this._run(query.replace(wrapped, opts), 'update', diag); | ||
if (postUnique) { | ||
return postUnique(result.changes); | ||
} | ||
} | ||
@@ -329,20 +349,20 @@ | ||
const changes = {}; | ||
changes[field] = RethinkDB.row(field).add(value); | ||
const track = { table: this.name, action: 'next', inputs: { id, field, value } }; | ||
const diag = { id, field, value }; | ||
try { | ||
const changes = {}; | ||
changes[field] = RethinkDB.row(field).add(value); | ||
id = Id.normalize(id, false); | ||
const result = await this._db._run(this.raw.get(id).update(changes, { returnChanges: true }), track); | ||
if (!result.replaced) { | ||
throw new Error('No item found to update'); | ||
} | ||
const inc = result.changes[0].new_val[field]; | ||
return inc; | ||
} | ||
catch (err) { | ||
throw this._error('next', err.message, diag); | ||
throw internals.Table.error(err, track); | ||
} | ||
const result = await this._run(this.raw.get(id).update(changes, { returnChanges: true }), 'next', diag); | ||
if (!result.replaced) { | ||
throw this._error('next', 'No item found to update', diag); | ||
} | ||
const inc = result.changes[0].new_val[field]; | ||
return inc; | ||
} | ||
@@ -352,26 +372,26 @@ | ||
const diag = { criteria }; | ||
const track = { table: this.name, action: 'remove', inputs: { criteria } }; | ||
const isBatch = Array.isArray(criteria); | ||
const isIds = (isBatch || typeof criteria !== 'object' || criteria.id !== undefined); | ||
if (isIds) { | ||
try { | ||
try { | ||
const isBatch = Array.isArray(criteria); | ||
const isIds = (isBatch || typeof criteria !== 'object' || criteria.id !== undefined); | ||
if (isIds) { | ||
criteria = Id.normalize(criteria, true); | ||
} | ||
catch (err) { | ||
throw this._error('remove', err.message, diag); | ||
} | ||
} | ||
const selection = (!isIds ? this.raw.filter(criteria) | ||
: (isBatch ? this.raw.getAll(RethinkDB.args(criteria)) | ||
: this.raw.get(criteria))); | ||
const selection = (!isIds ? this.raw.filter(criteria) | ||
: (isBatch ? this.raw.getAll(RethinkDB.args(criteria)) | ||
: this.raw.get(criteria))); | ||
const result = await this._run(selection.delete(), 'remove', diag); | ||
if (isIds && | ||
!isBatch && | ||
!result.deleted) { | ||
const result = await this._db._run(selection.delete(), track); | ||
if (isIds && | ||
!isBatch && | ||
!result.deleted) { | ||
throw this._error('remove', 'No item found to remove', diag); | ||
throw new Error('No item found to remove'); | ||
} | ||
} | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -381,4 +401,11 @@ | ||
const result = await this._run(this.raw.delete(), 'empty'); | ||
return result.deleted; | ||
const track = { table: this.name, action: 'empty' }; | ||
try { | ||
const result = await this._db._run(this.raw.delete(), track); | ||
return result.deleted; | ||
} | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -388,11 +415,13 @@ | ||
if (!this._db._connection) { | ||
throw this._error('sync', 'Database disconnected'); | ||
} | ||
const track = { table: this.name, action: 'sync' }; | ||
try { | ||
if (!this._db._connection) { | ||
throw new Error('Database disconnected'); | ||
} | ||
await this.raw.sync().run(this._db._connection); | ||
} | ||
catch (err) { | ||
throw this._error('sync', err); | ||
throw internals.Table.error(err, track); | ||
} | ||
@@ -403,25 +432,32 @@ } | ||
const pending = []; | ||
const names = []; | ||
indexes = [].concat(indexes); | ||
for (let i = 0; i < indexes.length; ++i) { | ||
let index = indexes[i]; | ||
if (typeof index === 'string') { | ||
index = { name: index }; | ||
} | ||
const track = { table: this.name, action: 'index' }; | ||
const { name, source, options } = index; | ||
names.push(name); | ||
try { | ||
const pending = []; | ||
const names = []; | ||
indexes = [].concat(indexes); | ||
for (let i = 0; i < indexes.length; ++i) { | ||
let index = indexes[i]; | ||
if (typeof index === 'string') { | ||
index = { name: index }; | ||
} | ||
const args = [name]; | ||
if (source) { | ||
args.push(Array.isArray(source) ? source.map((row) => RethinkDB.row(row)) : source); | ||
const { name, source, options } = index; | ||
names.push(name); | ||
const args = [name]; | ||
if (source) { | ||
args.push(Array.isArray(source) ? source.map((row) => RethinkDB.row(row)) : source); | ||
} | ||
args.push(options); | ||
pending.push(this._db._run(this.raw.indexCreate.apply(this.raw, args), track)); | ||
} | ||
args.push(options); | ||
pending.push(this._run(this.raw.indexCreate.apply(this.raw, args), 'index')); | ||
await Promise.all(pending); | ||
return this._db._run(this.raw.indexWait(RethinkDB.args(names)), track); | ||
} | ||
await Promise.all(pending); | ||
return this._run(this.raw.indexWait(RethinkDB.args(names)), 'indexWait'); | ||
catch (err) { | ||
throw internals.Table.error(err, track); | ||
} | ||
} | ||
@@ -431,4 +467,6 @@ | ||
const track = { table: this.name, action: 'changes', inputs: { criteria } }; | ||
if (!this._db._connection) { | ||
throw this._error('changes', 'Database disconnected', criteria); | ||
throw internals.Table.error(new Error('Database disconnected'), track); | ||
} | ||
@@ -471,3 +509,3 @@ | ||
catch (err) { | ||
throw this._error('changes', err, criteria); | ||
throw internals.Table.error(err, track); | ||
} | ||
@@ -514,3 +552,3 @@ | ||
return options.handler(this._error('changes', err, criteria, { disconnected, willReconnect })); | ||
return options.handler(internals.Table.error(err, track, { disconnected, willReconnect })); | ||
}); | ||
@@ -521,36 +559,9 @@ | ||
_run(request, action, inputs) { | ||
static error(err, { table, action, inputs }, flags) { | ||
return this._db._run(request, {}, this.name, action, inputs); | ||
} | ||
_error(action, err, inputs, flags) { | ||
return internals.error(this.name, action, err, inputs, flags); | ||
} | ||
static _error(table, action, err, inputs, flags) { | ||
return internals.error(table, action, err, inputs, flags); | ||
} | ||
}; | ||
internals.error = function (table, action, err, inputs, flags) { | ||
const message = (typeof err === 'string' ? err : err.message); | ||
const data = { error: err, table, action, inputs }; | ||
if (err instanceof Error) { | ||
data.error.stack = err.stack; | ||
data.error.message = err.message; | ||
} | ||
const error = Boom.internal(message, data); | ||
if (flags) { | ||
const error = Boom.boomify(err); | ||
error.data = { table, action, inputs }; | ||
error.flags = flags; | ||
return error; | ||
} | ||
return error; | ||
}; |
{ | ||
"name": "penseur", | ||
"description": "Lightweight RethinkDB wrapper", | ||
"version": "8.0.0", | ||
"version": "8.0.1", | ||
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)", | ||
@@ -12,3 +12,3 @@ "repository": "git://github.com/hueniverse/penseur", | ||
"engines": { | ||
"node": ">=8.7.0" | ||
"node": ">=8.8.0" | ||
}, | ||
@@ -15,0 +15,0 @@ "dependencies": { |
@@ -32,8 +32,8 @@ # penseur | ||
#### `db.connect(callback)` | ||
#### `await db.connect()` | ||
Create a connection to the database. `callback` is a function with the signature `function(err)` that is executed when the connection is established or an error occurs establishing the connection. | ||
Create a connection to the database. Throws connection errors. | ||
#### `db.close([next])` | ||
#### `await db.close()` | ||
@@ -43,3 +43,3 @@ Close all database connections. | ||
#### `db.establish([tables], callback)` | ||
#### `await db.establish([tables])` | ||
@@ -51,3 +51,2 @@ Note that this can alter data and indexes, not intended of production use. | ||
- `[tables]` - array of strings with the name of each table to create | ||
- `callback` - function with signature `function(err)` that is executed when everything succeeds or an error is encountered. | ||
@@ -82,3 +81,3 @@ | ||
#### `db[table].get(id, [options, ] callback)` | ||
#### `await db[table].get(id, [options])` | ||
@@ -94,21 +93,17 @@ Retrieve a record in the `table` with the given `id`. `id` itself can be an array of `id` values if you want to retrieve multiple records. | ||
- `filter` - properties to pluck from the results | ||
- `callback` - function with `function(err, results)` signature | ||
#### `db[table].all(callback)` | ||
#### `await db[table].all()` | ||
Retrieve all records for a table. | ||
- `callback` - function with `function(err, results)` signature | ||
#### `await db[table].exist(id)` | ||
#### `db[table].exist(id, callback)` | ||
Determine if a record in the `table` exists with the provided ID | ||
- `id` - unique identifier of record to retrieve. Can be an array with values for each ID to retrieve. | ||
- `callback` - function with `function(err, exists)` signature | ||
#### `db[table].query(criteria, callback)` | ||
#### `await db[table].query(criteria)` | ||
@@ -118,6 +113,5 @@ Perform a query on the table using the provided criteria. Criteria is available on the `Db` object and is listed in the criteria section below. | ||
- `criteria` - db [criteria](#criteria) functions chained together | ||
- `callback` - function with `function(err, results)` signature | ||
#### `db[table].single(criteria, callback)` | ||
#### `await db[table].single(criteria)` | ||
@@ -127,6 +121,5 @@ Retrieve a single record from the provided criteria. | ||
- `criteria` - db [criteria](#criteria) functions chained together | ||
- `callback` - function with `function(err, result)` signature | ||
#### `db[table].count(criteria, callback)` | ||
#### `await db[table].count(criteria)` | ||
@@ -136,6 +129,5 @@ Retrieve the number of records in the table that match the given criteria. | ||
- `criteria` - db [criteria](#criteria) functions chained together | ||
- `callback` - function with `function(err, count)` signature | ||
#### `db[table].insert(items, [options, ] callback)` | ||
#### `await db[table].insert(items, [options])` | ||
@@ -148,6 +140,5 @@ Create new record(s) in the table. Each item can specify a unique `id` property or allow rethink to generate one for them. | ||
- `chunks` - maximum number of updates to send to the database at the same time | ||
- `callback` - function with `function(err, keys)` signature | ||
#### `db[table].update(ids, changes, callback)` | ||
#### `await db[table].update(ids, changes)` | ||
@@ -158,6 +149,5 @@ Update an existing record with the provided changes. | ||
- `changes` - the parts of the record to change and the values to change the parts to | ||
- `callback` - function with `function(err)` signature | ||
#### `db[table].update(updates, [options, ] callback)` | ||
#### `await db[table].update(updates, [options])` | ||
@@ -169,6 +159,5 @@ Update an existing record with the provided changes. | ||
- `chunks` - maximum number of updates to send to the database at the same time | ||
- `callback` - function with `function(err)` signature | ||
#### `db[table].remove(criteria, callback)` | ||
#### `await db[table].remove(criteria)` | ||
@@ -178,28 +167,22 @@ Remove the records in the table that match the given criteria. | ||
- `criteria` - db [criteria](#criteria) functions chained together | ||
- `callback` - function with `function(err)` signature | ||
#### `db[table].empty(callback)` | ||
#### `await db[table].empty()` | ||
Remove all records in the table. | ||
- `callback` - function with `function(err)` signature | ||
#### `await db[table].sync()` | ||
#### `db[table].sync(callback)` | ||
Wait until all operations are complete and all data is persisted on permanent storage. Note that this function shouldn't be necessary for normal conditions. | ||
- `callback` - function with `function(err)` signature | ||
#### `await db[table].index(indexes)` | ||
#### `db[table].index(indexes, callback)` | ||
Create the secondary `indexes` on the table. | ||
Create the secondary `indexes` on the table. `callback` is executed when all of the indexes are created. | ||
- `indexes` - a string or array of strings for each index to create | ||
- `callback` - function with `function(err)` signature | ||
#### `db[table].changes(criteria, [options,] [callback])` | ||
#### `await db[table].changes(criteria, [options])` | ||
@@ -210,6 +193,5 @@ Subscribe to changes matching the given criteria for the table. | ||
- `options` - optional object with the following properties | ||
- `handler` - handler function to execute when changes occur. When provided the `callback` function can be omitted. | ||
- `handler` - handler function to execute when changes occur. | ||
- `reconnect` - boolean, reconnect if the connection to the feed is interrupted | ||
- `initial` - boolean, include the initial results in the change feed | ||
- `callback` - function with `function(err, changes)` signature | ||
@@ -216,0 +198,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1602
67202
197