An improved version of the official Couchbase driver.
npm install couchbase-driver
A simple alternative driver for Couchbase that wraps the Bucket
from existing driver with the following modifications:
get
works on a single key or an array of keys, callingBucket.getMulti
if appropriate. Automatically handles key not found errors and doesn't return an error in that scenario. In case of multiple keys, optionally returns an array of missing keys.remove
also handles key not found errors more gracefully.getAndLock
also handles key not found errors more gracefully.- adds
atomic
function that tries to do performgetAndLock
+transform
+ specified database operation utilizingCAS
in one step until success or maximum retries have occurred. By default we usegetAndLock
to lock the document while we transform and perform document operation and unlock. Optionally we can use normalget
function. - adds
Promise
support so that functions call be called with either Node-style callbacks or with Promises. - adds option to automatically retry operations on Couchbase temporary errors. Uses
async.retry
and is configurable with thetempRetryTimes
,tempRetryInterval
andretryTemporaryErrors
options (defaults tofalse
). - adds
getServerVersion
function that attempts to get the server version from the cluster.
Creating:
const couchbase = require('couchbase');
const Driver = require('couchbase-driver');
const cluster = new couchbase.Cluster('couchbase://127.0.0.1');
const bucket = cluster.openBucket('default');
const driver = Driver.create(bucket);
Simple retrieval:
driver.get('my_doc_key', (err, res) => {
if (err) return console.log(err)
console.dir(res.value)
});
If key does not exist err
and res
will be undefined.
Getting multiple documents:
driver.get(['my_doc_key_1', 'my_doc_key_2', 'my_missing_doc_key_3'], (err, results, missing) => {
if (err) return console.log(err);
if (mising.length > 0) console.dir(missing); // ['my_missing_doc_key_3']
console.dir(res.value);
});
"Atomic" transformations can be achieved using the atomic
function which attempts to do get
+ transform
+
specified database operation where CAS
in get
and the final operation have to match. This uses async.retry
until successful or maximum retries have occurred,
which can be specified in the Driver
construction or as function option parameter.
function transform(doc) {
doc.foo = 'bar';
return {
value: doc,
action: Driver.OPERATIONS.UPSERT
};
}
driver.atomic('my_doc_key', transform, (err, res) => {
if(err) return console.dir(err);
console.dir(res);
});
With promises:
const result = await driver.get('mykey');
console.dir(result.value); // document
Note that with Promise style call and multiple keys we do not get misses.
const results = await driver.get(['mykey1', 'mykey2']);
console.dir(_.map(results, 'value')); // array of documents
A simple alternative driver for Couchbase that wraps the Bucket
from existing driver and improves
get
and remove
methods and adds atomic
method.
Kind: global class
- Driver
- new Driver(bucket, options)
- instance
- static
Constructs the new instance. This should not be called directly, but rather use Driver.create()
.
Param | Type | Description |
---|---|---|
bucket | Object |
the Couchbase Bucket |
options | Object |
Options |
options.retryTemporaryErrors | Boolean |
Whether to automatically backoff/retry on temporary couchbase errors. Default: false . |
options.tempRetryTimes | Number |
The number of attempts to make when backing off temporary errors. See async.retry . Default: 5 . |
options.tempRetryInterval | Number |
The time to wait between retries, in milliseconds, when backing off temporary errors . See async.retry . Default: 50 . |
options.atomicLock | Boolean |
Whether to use getAndLock in atomic() or just the standard get . Default: true . |
options.atomicRetryTimes | Number |
The number of attempts to make within atomic() . See async.retry . Default: 5 . |
options.atomicRetryInterval | Number |
The time to wait between retries, in milliseconds, within atomic() . See async.retry . Default: 0 . |
options.atomicLock | Boolean |
Whether to use getAndLock in atomic() or just the standard get . Default: true . |
options.missing | Boolean |
Whether to return missing. If false Does not return. Useful for certain contexts. Defalt: true . |
Get operation enums
Kind: instance property of Driver
Example
const Driver = require('couchbase-driver');
const driver = Driver.create(bucket);
console.log(driver.OPERATIONS.UPSERT);
A simplified get. Properly handles key not found errors. In case of multi call, returns array of found and an array of misses.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
keys | String | Array |
a single key or multiple keys |
options | Object |
Options for bucket get function |
options.missing | Boolean |
Whether to return missing. If false Does not return. Useful for certain contexts. This option takes presidence over the one set in constructor. Default: true . |
fn | function |
callback |
Example
driver.get('my_doc_key', (err, res) => {
if (err) return console.log(err)
console.dir(res.value)
}
Example
driver.get(['my_doc_key_1', 'my_doc_key_2', 'my_missing_doc_key_3'], (err, results, missing) => {
if (err) return console.log(err);
if (mising.length > 0) console.dir(missing); // ['my_missing_doc_key_3']
console.dir(res.value);
});
Our implementation of Bucket.getAndLock
that properly ignores key not found errors.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
key | String |
document key to get and lock |
options | Object |
Options to pass to Bucket.getAndLock |
fn | function |
callback |
Example
driver.getAndLock('my_doc_key', (err, res) => {
if (err) return console.log(err);
console.dir(res.value)
});
Our implementation of Bucket.remove
that properly ignores key not found errors.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
key | String |
document key to remove |
options | Object |
Options to pass to Bucket.remove |
fn | function |
callback |
Example
driver.remove('my_doc_key', (err, res) => {
if (err) return console.log(err);
});
Our implementation of Bucket.insert
that can recover from temporary errors.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
key | String |
document key to insert |
value | String |
document contents to insert |
options | Object |
Options to pass to Bucket.insert |
fn | function |
callback |
Example
driver.insert('my_doc_key', "doc_contents", (err, res) => {
if (err) return console.log(err);
});
Our implementation of Bucket.upsert
that can recover from temporary errors.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
key | String |
document key to upsert |
value | String |
document contents to upsert |
options | Object |
Options to pass to Bucket.upsert |
fn | function |
callback |
Example
driver.upsert('my_doc_key', "doc_contents", (err, res) => {
if (err) return console.log(err);
});
Performs an "atomic" operation where it tries to first get the document given the key
, then perform
the function transform
on the value and then write using the CAS value in the upsert
.
If the final document operation fails due to a CAS
error, the whole process is retried.
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
key | String |
document key |
transform | function |
synchronous function to be performend on the document value. Function accepts the document or undefined if the document was not found. The function should perform any necessary mutation and return an object with value and action . value is the new value of the document. action should be one of OPERATIONS specifying the action to take with the new value. |
options | String |
Options |
options.atomicRetryTimes | Number |
The number of attempts to make within atomic() . See async.retry . Default: 5 . |
options.atomicRetryInterval | Number |
The time to wait between retries, in milliseconds, within atomic() . See async.retry . Default: 0 . |
options.atomicLock | Boolean |
Whether to use getAndLock in atomic() or just the standard get . Default: true . |
options.saveOptions | Object |
bucket save options |
fn | function |
callback |
Example
function transform(doc) {
doc.foo = 'bar';
return {
value: doc,
action: OPERATIONS.UPSERT
};
}
driver.atomic('my_doc_key', transform, (err, res) => {
if(err) return console.log(err);
console.dir(res);
});
Attempts to get the lowest couchbase server version from the nodes in the cluster.
Warning This depends on undocumented internals of Node.js couchbase library
Kind: instance method of Driver
Param | Type | Description |
---|---|---|
fn | function |
callback |
Example
driver.getServerVersion((err, version) => {
if(err) return console.log(err);
console.log(version);
});
Get operation enums
Kind: static property of Driver
Example
const Driver = require('couchbase-driver');
console.log(Driver.OPERATIONS.UPSERT);
Enum for Database operations
Kind: static enum of Driver
Read only: true
Properties
Name | Type | Default | Description |
---|---|---|---|
UPSERT | string |
"upsert" |
Upsert operation |
REMOVE | string |
"remove" |
Remove operation |
NOOP | string |
"noop" |
No operation or action |
Determines if error is a "key not found" error
Kind: static method of Driver
Param | Type | Description |
---|---|---|
err | Error |
the error to check |
Example
Driver.isKeyNotFound(err);
Determines if error is a "Temporary" error https://developer.couchbase.com/documentation/server/current/sdk/nodejs/handling-error-conditions.html
Kind: static method of Driver
Param | Type | Description |
---|---|---|
err | Error |
the error to check |
Example
Driver.isTemporaryError(err);
Driver.create(bucket, options) ⇒ Driver
Create a Driver object by wrapping the Couchbase bucket and creates a new Driver
instance and
adds Promise
support to the instance.
Kind: static method of Driver
Param | Type | Description |
---|---|---|
bucket | Object |
The Couchbase Bucket instance to wrap. |
options | Object |
Options |
options.retryTemporaryErrors | Boolean |
Whether to automatically backoff/retry on temporary couchbase errors. Default: false . |
options.tempRetryTimes | Number |
The number of attempts to make when backing off temporary errors. See async.retry . Default: 5 . |
options.tempRetryInterval | Number |
The time to wait between retries, in milliseconds, when backing off temporary errors . See async.retry . Default: 50 . |
options.atomicRetryTimes | Number |
The number of attempts to make within atomic() . See async.retry . Default: 5 . |
options.atomicRetryInterval | Number |
The time to wait between retries, in milliseconds, within atomic() . See async.retry . Default: 0 . |
options.atomicLock | Boolean |
Whether to use getAndLock in atomic() or just the standard get . Default: true . |
Example
const couchbase = require('couchbase');
const Driver = require('couchbase-driver');
const cluster = new couchbase.Cluster('couchbase://127.0.0.1');
const bucket = cluster.openBucket('default');
const driver = Driver.create(bucket);
debug package is used for debug logging.
DEBUG=couchbase-driver node app.js
Copyright 2015 Bojan D.
Licensed under the MIT License.