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

rowler

v1.1.2

Published

Document and Query Layer for CockroachDB

Downloads

7

Readme

Rowler - NodeJS Document and Query Layer for CockroachDB

A NodeJS Layer for CockroachDB that provides documents and queries with similar capabilities to MongoDB but providing support for multidocument transactions.

Transaction support is an incredile powerful feature that simplifies server logic and helps avoiding difficult to solve race conditions.

Fowl provides a low level API based on keypaths for describing documents and its properties following CRUD semantics.

Fowl aims to be a low level document layer that can be used by others to provide higher level features such as schemas, models, validation, etc.

All asynchronous operations return A+ compliant promises (provided by bluebirdjs).

Contribute

Do you like rowler and want to bring it up to the next level? Do not hesitate to clone the project and start contributing to it! :)

Install

npm install rowler

Test

npm test

Features

  • Clean API based on promises
  • Complete transaction support for all available operations.
  • Supports: create, get, update, remove, and find.
  • Access of documents and subdocuments seamless due to a keypath based design.

Roadmap

  • namespaces
  • Advanced queries (implement all mongodb query operators)
  • Joins
  • Profile and optimize

Documentation

Example

// Open a CockroachDB database
rowler.open();

// Create a document (if _id not specify a GUID will be generated)
var john = rowler.create('people', {
  _id: 'john',
  name: 'John',
  lastname: 'Smith',
  balance: 100
});

var lisa = rowler.create('people', {
  _id: 'lisa',
  name: 'Lisa',
  lastname: 'Jones',
  balance: 80
});

// Use transactions to transfer money from one account to another
rowler.transaction(function(tr){
  Promise.all([
    tx.get(['people', 'john']),
    tx.get(['people', 'lisa'])
  ]).spread(function (john, lisa) {
    john.balance -= 10;
    lisa.balance += 10;

    tr.put(['people', 'john'], john);
    tr.put(['people', 'lisa'], lisa);
}).then(function(){
  // We need to wait for the commit to complete since we are finding the
  // same keypaths.

  rowler.find('people', {balance: 90}, ['lastname']).then(function(docs){
    // docs = [{lastname: 'Jones'}, {lastname: 'Smith'}]
  })
})

In order to accelerate queries you should use indexes on the most common fields in a document. Just add indexes specifying a base key path and the fields to index:

rowler.addIndex('people',  ['name', 'balance']);

It is possible to perform more advanced queries using the Query object:

var query = rowler.query('people');
query
  .eql('lastname', 'Andersson')
  .gt('balance', 15)
  .lte('balance', 45)
  .exec(tr).then(function(results){
    // results -> array of documents matching the query.
  })

About atomicity

All CRUD functions are atomic. Meaning that updating or getting a document is fully atomic and you either update or get a full document or nothing at all.

The transaction object provides this same CRUD operations as atomic operations spawning multiple documents.

About Key Paths

Key paths are used in rowler to represent the location of some document or subdocument. It is just an array of strings (or numbers) that maps to a key or key range inside CockroachDB. Key paths are more flexible than bucket based collections, as used for example in mongoDB, since it allows you to specify a document or subdocument in a generic way.

For example:

// Specify a document for some user in bucket 'people'
['people', '60abd640-2d98-11e3-a7d8-bd61eca52c5c']

// Specify a location of all the songs in a playlist
['playlist', '60af31a0-2d98-11e3-a7d8-bd61eca52c5c', 'songs']

All methods accepting a key path as parameter also accept a string that will just be converted to an array:

'people' -> ['people']

About the _id property

As in MongoDB, we generate a unique _id property as a primary key for all the created documents.

This property can be overrided if required by providing it explicitly in the document object.

It is also possible skip the use of the _id property by just using the put method directly and never calling create.

Methods

Opens a CockroachDB database. This function is just a wrapper on top of new Roach You need to call this method before you can start using the rest of the API.

Arguments

    clusterFile {String} Optional path to a cluster file.
    dbName {String} Optional database name.

Creates a new document in the given key path. The document must be a plain object without any circular dependencies. Returns a promise that will resolve to the document _id property.

Arguments

    keyPath {Array|String} Keypath with the target location for the document.
    doc {Object} A plain object representing the document to store.
    returns {Promise} A promise that resolves to the document _id property.

Updates a document. Similar to create but will not generate any _id property automatically.

Arguments

    keyPath {Array|String} Keypath with the target location for the document.
    doc {Object} A plain object representing the document to store.
    returns {Promise} A promise that resolves after the document has been updated.

Retrieves the document at the given key path.

Arguments

    keyPath {Array|String} Keypath with the target location for the document.
    returns {Promise} A promise that resolves with the retrieved document.

Removes the document/subdocument at the given key path.

Arguments

  keyPath {Array|String} Keypath with the target location for the document to remove.
  returns {Promise} A promise that resolves after the removal.  

Finds documents in the given keypath that meets certain criteria.

Arguments

  keyPath {Array|String} Keypath with the target location of the documents to find
  filter {Object} An object mapping properties to their values.
  fields {Array} An options array of property names that should be returned.
  returns {Promise} A promise that resolves with the found documents.

Creates a new transaction. A transaction is an object that provides methods to access the database as an atomic operation.

When calling this method, a new transaction object will be created and passed to the provided callback function. Once that callback returns, the transaction will automatically commit. The callback may return a Promise to delay the commit.

If the callback throws an exception (or rejects its Promise), roachjs's retry logic will apply. Transactions may also be retried due to committing with unknown result which means developers should ensure transactions are idempotent.

Arguments

  transactionBody(transaction) {Function} This method should contain all
    transaction operations and may return a Promise in which case the commit
    will take place when that Promise is resolved.
  returns {Promise} A promise that resolves after the transaction has executed.

transaction##create()

A transactional equivalent to rowler##create

transaction##put()

A transactional equivalent to rowler##put

transaction##get()

A transactional equivalent to rowler##get

transaction##remove()

A transactional equivalent to rowler##remove

transaction##find()

A transactional equivalent to rowler##find

Adds an index for the given key path and fields. After calling this method, everytime the key paths with the given fields are updated, an index is also updated so that queries on such fields can be performed much faster.

Arguments

  keyPath {Array|String} base key path for the index.
  fields {String|Array} A field or array of fields to index.
  returns {Promise} A promise that resolves after the index has been added.

Creates a query object that can be used to retrieve documents that matches the given criteria. The returned query object provides several operators to perform different kind of queries. The query object will use indexes to accelerate queries if possible. Note that the order of the operators can affect performance, it is always better to use indexed properties first.

Arguments

  keyPath {Array|String} base key path for the query.
  fields {String|Array} A field or array of fields to return on the matched documents.
  opts {Options} Available options are "limit", "skip" and "sort".
  returns {Query} A query object with several operators to match the documents.

query##eql(property, value)

Matches documents where the given property is equal to the given value.

query##gt(property, value)

Matches documents where the given property is greather than the given value.

query##gte(property, value)

Matches documents where the given property is greater or equal than the given value.

query##lt(property, value)

Matches documents where the given property is less than the given value.

query##lte(property, value)

Matches documents where the given property is less or equal than the given value.

query##exec(transaction)

Executes the query. Returns a promise that resolves to the result of the query.

License

(The MIT License)

Copyright (c) 2014 Stefan Thomas [email protected] Copyright (c) 2013 Manuel Astudillo [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.