riak-js

Extensible Javascript library for accessing Riak

index

../lib/index.js

Get a riak-js client

  • param: Object Initial options, that will apply for the whole session

  • return: Riak The riak-js client

  • api: public

exports.getClient = function(options) {
  var Riak = require('./riak-node')
  return new Riak(options)
}

riak

../lib/riak.js

Module dependencies

var utils = require('./utils'),
  Meta = require('./meta'),
  Mapper = require('./mapper');

Client defaults

Riak.prototype.defaults = {
  clientId: 'riak-js', 
  method: 'GET',
  interface: 'riak',
  headers: { 'content-type': 'application/json', 'Host': "" },
  debug: true,
  callback: function(response, meta) {
    if (response)
      Riak.prototype.log(meta.type === 'application/json' ? JSON.stringify(response) : response)
  }
}

Fetches a value by key

  • param: String bucket

  • param: String key

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.get = function(bucket, key, options) {
  options = utils.ensure(options);
  options.key = key;
  return this.execute(utils.path(bucket, key), options);
}

Fetches all values in a bucket

  • options
    • where: filters by property (db.getAll('users', {where: {city: "Paris", age: 23}})), works on Riak 0.12+
    • withId: returns values with its

The first argument passed to the callback is an Array holding the results, or an Array holding [key, value]s

  • param: String bucket

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.getAll = function(bucket, options) {
  options = utils.ensure(options);
  if (options.where) {
    return this.map('Riak.mapByFields', options.where).run(bucket)
  }
  if (options.withId) {
    return this.map(function(v) { return [[v.key, v.values[0].data]] }).run(bucket)
  }
  return this.map('Riak.mapValues').run(bucket)
}

Fetches the key count for a bucket

  • param: String bucket

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.count = function(bucket, options) {
  options = utils.ensure(options);
  return this.map('Riak.mapValues').reduce(function(v) { return [v.length] }).run(bucket)
}

Fetches only the key's value metadata

  • param: String bucket

  • param: String key

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.head = function(bucket, key, options) {
  options = utils.ensure(options);
  options.method = 'HEAD';
  options.key = key;
  return this.execute(utils.path(bucket, key), options);
}

Removes a value

  • param: String bucket

  • param: String key

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.remove = function(bucket, key, options) {
  options = utils.ensure(options);
  options.method = 'DELETE';
  options.key = key;
  return this.execute(utils.path(bucket, key), options);
}

Removes all values from a bucket

IMPORTANT: This issues several requests

  • param: String bucket

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.removeAll = function(bucket, options) {
  options = utils.ensure(options),
    self = this;
  options.keys = true;
  return function(callback) {
    callback = callback || options.callback;

    self.get(bucket, undefined, options)(function(response) {
      response.keys.forEach(function(key) {
        self.remove(bucket, key, options)(callback);
      })
    })    
  }
}

Saves a value

  • param: String bucket

  • param: String key

  • param: Object data - the value to be stored

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.save = function(bucket, key, data, options) {
  data = utils.ensure(data);
  options = utils.ensure(options);
  if (!options.method)
    options.method = key ? 'PUT' : 'POST';
  options.data = data;
  options.key = key;

  return this.execute(utils.path(bucket, key), options);
}

Link-walks from a given bucket/key

This implementation uses Map/Reduce

  • param: String bucket from where to start the link-walk

  • param: String key from where to start the link-walk

  • param: Array spec - a link-walking spec, such as [["bucket", "tag"]]

  • param: Object options - overrides default options and specifies particular options for this operation

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.walk = function(bucket, key, spec, options) {
  var linkPhases = spec.map(function(unit) {
    return { bucket: unit[0] || '_', tag: unit[1] || '_', keep: unit[2] ? true : false }
  });
    
  return this
    .link(linkPhases)
    .reduce({ language: 'erlang', module: 'riak_kv_mapreduce',
      'function': 'reduce_set_union'})
    .map("Riak.mapValuesJson")
    .run(key ? [[bucket, key]] : bucket, options);
}

Pings the node this client is currently connected to

  • return: Function A function that takes a callback as its only input

  • api: public

Riak.prototype.ping = function() {
  return this.head('', '', {interface: 'ping'})
}

Handy method to check whether the response was an error or not

Usage: if (db.error(response)) { ... }

  • return: Boolean true if it's an Error

  • api: public

Riak.prototype.error = function(response) {
  return response instanceof Error
}

Convenience method to help construct a Mapper object to achieve a chainable Map/Reduce-API, initializing it with one or more map phases

  • return: Mapper

  • api: public

Riak.prototype.map = function(phase, args) {
  return new Mapper(utils.makePhases("map", phase, args), this)
}

Convenience method to help construct a Mapper object to achieve a chainable Map/Reduce-API, initializing it with one or more reduce phases

  • return: Mapper

  • api: public

Riak.prototype.reduce = function(phase, args) {
  return new Mapper(utils.makePhases("reduce", phase, args), this)
}

Convenience method to help construct a Mapper object to achieve a chainable Map/Reduce-API, initializing it with one or more link phases

  • return: Mapper

  • api: public

Riak.prototype.link = function(phase) {
  return new Mapper(utils.makePhases("link", phase), this)
}

mapper

../lib/mapper.js

Module dependencies

var utils = require('./utils')

Add one or more map phases to the Map/Reduce job

  • param: Object One (function, string, or object containing source, name, args, etc) or more phases (each one contained in an Array)

  • return: Mapper To be able to chain until #run() is called

  • api: public

Mapper.prototype.map = function(phase, args) {
  this.addPhases(utils.makePhases("map", phase, args))
  return this;
}

Add one or more reduce phases to the Map/Reduce job

  • param: Object One (function, string, or object containing source, name, args, etc) or more phases (each one contained in an Array)

  • return: Mapper To be able to chain until #run() is called

  • api: public

Mapper.prototype.reduce = function(phase, args) {
  this.addPhases(utils.makePhases("reduce", phase, args))
  return this;
}

Add one or more link phases to the Map/Reduce job

  • param: Object One (function, string, or object containing source, name, args, etc) or more phases (each one contained in an Array)

  • return: Mapper To be able to chain until #run() is called

  • api: public

Mapper.prototype.link = function(phase) {
  this.addPhases(utils.makePhases("link", phase))
  return this;
}

Run the Map/Reduce job

  • param: Array for a list of [bucket, key], or {String} for a bucket name (warning: it has to list the bucket's keys)

  • return: Function A function that takes a callback as its only input

  • api: public

Mapper.prototype.run = function(inputs, options) {
  options = utils.ensure(options);
  options.interface = 'mapred';
  options.method = 'POST';

  this.phases.forEach(function(phase) {
    for (p in phase) { // map, reduce or link
      if (phase[p].language === undefined) {
        phase[p].language = 'javascript';
      };
    }
  })
  
  options.data = {
    inputs: inputs,
    query: this.phases
  }

  return this.riak.execute('', options);
}

meta

../lib/meta.js

Module dependencies

var utils = require('./utils')

Removes a link from the current list of links

  • param: Object Link, such as {bucket: 'bucket', key: 'mykey'}

  • api: public

Meta.prototype.removeLink = function(link) {
  this.headers.link = this.makeLinks(this.links.filter(function(n) {
    return n.bucket !== link.bucket || n.key !== link.key
  }))
}

Link getter

  • return: Array All the links in the current list of links

  • api: public

Meta.prototype.__defineGetter__('links', function() {
  return utils.stringToLinks(this.headers.link)
})

Link setter (one, or more in an Array)

  • param: Object {Array} Link(s)

  • api: public

Meta.prototype.__defineSetter__('links', function(links) {
  if (!utils.isArray(links)) links = [links]
  this.headers.link = (this.headers.link ? this.headers.link + ", " : "") + this.makeLinks(links)
})