npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

roachjs

v0.2.20

Published

Node.js driver for cockroachdb.

Downloads

87

Readme

RoachJS - CockroachDB Driver

NPM

Build Status

Introduction

This client is a port from the original Golang client. Internally it's is more or less the same, but this driver provides a friendlier javascript interface.

Installation

$ npm install roachjs

Documentation

Examples

Initiating a client

var Roach = require('roachjs')

var client = new Roach({
    uri: 'https://localhost:8080'
})

module.exports = client

Basic client usage I

client.get("sample_key", function(err, value, res) {
    if(err) throw err

    client.put("other_key", value, function(err, res) {
        if(err) {
            // Failed
        }
        else {
            // Sucess
        }
    })
})

Advanced client usage I (Prepare & Flush)

// You should prepare your queries and send them in a single batch
// For optimal performance
var c = client.prepare()

// This callback will be the first to be executed
c.get("sample_key", function(err, value, res) {
    if(err) throw err

    // Do something...
})

c.get("sample_key2", function(err, value, res) {
    if(err) throw err

    // Do something...
})

c.put("some_key", "some_value", function(err) {
    if(err) throw err

    // Do something
})

// The flush callback is the last one to be called
c.flush(function(err, res) {
    if(err) throw err

    console.log('Sucessfuly flushed %d queries.', res.responses.length)
})

Advanced client usage II (Transactions)

var opts = {
    name: "transaction example",
}

var errNoApples = new Error('Insufficient apples!')

var transaction = function(txn, commit, abort) {
    txn.get("applesInStock", function(err, value, res) {
        if(err || applesInStock.err) {
                return abort(err)
            }

            var dispatch = 5
            var inStock = parseInt(applesInStock.value)

            if(inStock < dispatch) {
                return abort(errNoApples)
        }

        // Upgrade for a prepared client
        txn = txn.prepare()

        txn.increment("applesInStock", -dispatch)
        txn.increment("applesInRoute", +dispatch)

        // Commit automatically flushes
        commit()
    })
}

client.runTransaction(opts, transaction, function(err, res) {
    if(err === errNoApples) {
        // Alert user there are no more apples...
    }
    else if(err) {
        // Transaction failed...
    }
    else {
        // Transaction commited...
    }
})

Interface

new Client(opts)

Returns a new roachjs client with options.

Parameters

name | type | description --- | --- | ---- opts | object | see

Client options

opt | description | default --- | --- | --- uri | uri to the cockroach http endpoint | https://localhost:8080/ host | host or ip to the cockroach http endpoint | localhost port | port to the cockroach http endpoint | 8080 ssl | connect throught https | true user | user to run the requests with | root retry | retry requests when cockroach responds with a busy signal | true http | http module to use | require('https') agent | http agent to use on the requests (read more) | new http.Agent() clock | clock module to use (read more)| internal clock module

Methods

| method | | --- | | get | | put | | conditionalPut | | contains | | increment | | scan | | delete | | deleteRange | | prepare | | runTransaction |

client.get(key, callback)

Gets a single entry from the datastore, specified by key.

Parameters

name | type | description --- | --- | ---- key | string | callback | callback | function(err, value, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | value | Buffer | res | object | see

Example
client.get("key", function(err, value, res) {})

client.put(key, value, callback)

Puts a value in the datastore in the specified key. Ideally you should send in buffers, but you can pass a string, preferably an utf-8 encoded string.

Parameters

name | type | description --- | --- | ---- key | string | value | Buffer, string | callback | callback | function(err, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | res | object | see

Example
client.put("key", "value", function(err, res) {})

client.conditionalPut(key, value, ifValue, callback)

ConditionalPut sets the value for a key if the existing value matches the ifValue. Specifying an empty or null ifValue means the entry must not yet exist.

Parameters

name | type | description --- | --- | ---- key | string | value | Buffer, string | ifValue | Buffer, string, null | use null to put if entry doens't exists callback | callback | function(err, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | actualValue | Buffer | If conditional put fails this value is set res | object | see

Example
client.conditionalPut("status", "running", "stopped", function(err, actualValue, res) {})
client.conditionalPut("status", "new", null, function(err, actualValue, res) {})

client.contains(key, callback)

Contains determines if a key exists in the datastore.

Parameters

name | type | description --- | --- | ---- key | string | callback | callback | function(err, exists, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | exists | boolean | res | object | see

Example
client.contains("john", function(err, exists, res) {
    if(exists === true) {
        // john exists in the datastore
    }
})

client.increment(key, increment, callback)

Increment increments the value at the specified key by some increment value. Once called for a key, Put & Get will return errors; only Increment will continue to be a valid command. The value must be deleted before it can be reset using Put.

Parameters

name | type | description --- | --- | ---- key | string | increment | integer | callback | callback | function(err, newValue, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | newValue | integer | the new value for this counter, after the increment operation res | object | see

Example
client.increment("counter", 5, function(err, newValue, res) {
    console.log('counter current value is', newValue)
})

client.scan(start_key, end_key, limit, callback)

Scan the datastore for keys in the range of the start_key and end_key, limiting the result by limit.

Parameters

name | type | description --- | --- | ---- key | string | start_key | string | end_key | string | limit | integer | callback | callback | function(err, rows, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | rows | array | res | object | see

Example
client.scan("a", "Z", 100, function(err, rows, res) {
    for(row as rows) {
        console.log(row)
    }
})

client.delete(key, callback)

Delete an entry from the datastore specified by key.

Parameters

name | type | description --- | --- | ---- key | string | callback | callback | function(err, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | res | object | see

Example
client.delete("key", function(err, res) {})

client.deleteRange(start_key, end_key, limit, callback)

Delete all keys found in a range, from start_key to end_key, limited by limit.

Parameters

name | type | description --- | --- | ---- key | string | start_key | string | end_key | string | limit | integer | callback | callback | function(err, deleted, res) {}

Callback

name | type | description --- | --- | ---- err | Error() | deleted | integer | number of entries deleted res | object | see

Example
client.deleteRange("a", "Z", 100, function(err, deleted, res) {
    console.log('deleted %d entries', deleted)
})

client.prepare()

Return you a new prepared client. It has all the methods from the original client. Read Advanced client usage II to understand how to use this client. You should always use this client when sending in multiple queries, this will batch them together in a single request.

Methods

| method | description | | --- | --- | | flush | Flush the prepared queries |

Example
var c = client.prepare()

c.get("key", function(err, value, res) {
    // Do something...
})

c.get("key2", function(err, value, res) {
    // Do something...
})

c.put("key3", "value", function(err, res) {
    // Do something...
})

c.flush()

client.flush(callback)

Flush the prepared queries buffer, and send it as a batch request.

Parameters

name | type | description --- | --- | ---- callback | callback | optional

Callback

name | type | description --- | --- | ---- err | Error() | batch request failed res | object | see

Example
client.flush(function(err, res) {
    if(err) {
        // Flush failed..
    }
    else {
        console.log('flushed %d queries.', res.responses.length)
    }
})
Returns

Returns an response object.

property | type | description --- | --- | ---- err | Error() | is null if no error was returned value | string, number, boolean | general response value res | object | see

client.runTransaction(opts, transaction, callback)

RunTransaction executes a retryable transaction function in the context of a distributed transaction. The transaction is automatically aborted if retryable function returns any error aside from recoverable internal errors, and is automatically committed otherwise. retryable should have no side effects which could cause problems in the event it must be run more than once. The opts contains transaction settings.

Parameters

name | type | description --- | --- | ---- opts | object | options transacation | retryable function | function(txn, commit, abort) {} callback | callback | function(err, res) {}

Transaction options

opt | description | default --- | --- | --- name | transaction name for debugging | "" isolation | | 0

Callback

name | type | description --- | --- | ---- err | Error() | if transaction fails res | object | see

Extra

Response properties

The res argument contains the full database response, each database command can contain a different set of properties. This document will try to state some of the possible properties.

Properties

property | type | description --- | --- | --- timestamp | integer | timestamp of the returned entry wall_time | integer | timestamp of when the read or write operation was performed

Transaction function

The transaction function is an retryable function, it may be executed more than once. This function should never forget to call commit or abort. Throwing an error inside this function also aborts the transaction.

Arguments

name | type | description --- | --- | ---- txn | Prepared client | this client is the same as client.prepare(), you can flush yourself if you don't wan't to commit yet. commit | callback | to try to commit transaction abort | callback | to abort transaction

  • abort() accepts an optional Error. This error will be passed to the .runTransaction callback.
Example
var transaction = function(txn, commit, abort) {
    txn = txn.prepare()

    for(var i = 0; i < 100; i++) {
        var key = i.toString()

        txn.put(key, "hello")
    }

    // Commit automatically flushes
    // the prepared transaction.
    commit()
}

Compiling .proto files

Cockroachdb's protocol buffer files are mantained at a repository called cockroachdb/cockroach-proto, this is maintained as a subtree in this library, in case you need to manually update or change them, follow this steps.

If you want to sync them with the latest proto files

You will need to update the folder cockroach-proto with the latest content of the cockroachdb/cockroach-proto repository, you could do this with:

$ git subtree pull -P cockroach-proto [email protected]:cockroachdb/cockroach-proto.git master --squash
  • Notice: I'm not sure if this is a good pattern, just be sure to update the folder contents.
Recompile the .proto files

Run the following npm script to compile the .proto files to javascript, it will automatically place the files in the lib folder.

$ npm run build-proto

Custom clock module

You may wan't to use a custom clock module in some cases, you can pass it through the clock option, when instantiating a new Client. Your clock module should have a now method, and this method should return the current timestamp in nanoseconds, here is an example:

var clockModule = module.exports = {
    now: function TimestampNanoseconds() {
        // Should return the current timestamp in nanoseconds
        return ...;
    }
}

var client = new Client({
    clock: clockModule
})

Maintainers