hw-store

0.0.2 • Public • Published

NPM version Build Status Coverage Status

hw-store

Hw-store allow you to persist your datas into any store like Redis, MongoDB, mySQL.

It provides a generic Datastore class that seamlessly wraps a database provider implementation.

For what need?

The goal of this project is to provide a light and easy way to persist small datas with different databases.

So if your need is to just save and retreive simple entities in any database system, then you're welcome.

On the other way, if you have to deal with big datas and scalability then you'd rather not use hw-store...

Installation

$ npm install hw-store --save

Additional provider installation

Depending of the db provider you want to use, you will need an additional module :

  • MongoDB :
$ npm install mongoose --save
  • mySQL :
$ npm install mysql --save
  • Redis :
$ npm install redis --save

Look at the examples in optionalDependencies of package.json

Getting started

Create an entity and get it back : mem-create-get

var Datastore = require('hw-store')
  , store, johnDoeId;

store = new Datastore({ // Configure the store
  // Choose any of the following providers (database systems)
  //db: Datastore.providers.MEM, // in-memory db (used by default)
  //db: Datastore.providers.REDIS, // Redis store (need npm install redis)
  //db: Datastore.providers.MONGODB, // MongoDB store (need npm install mongoose)
  //db: Datastore.providers.MYSQL, // mySQL store (need npm install mysql)
  models: { // Define the models to persist
    contact: { // 'contact' entities Schema
      firstName: 'string',
      lastName: 'string',
      email: 'string',
      vip: 'boolean',
      age: 'number'
    }
  }
});

store.start(function (err) {
  store.create(  // Add a contact to the store
    'contact', // Name of the entity model
    { // Object to persist
      firstName: 'john',
      lastName: 'doe',
      email: 'john@doe.com',
      vip: true,
      age: 25
    },
    function (err, contact) { // Returns the persisted object
      johnDoeId = contact.id;
      console.log('John Doe id :', johnDoeId);
      // next we want to get John Doe back
      getJohnDoe();
    });
});

function getJohnDoe() {
  store.get(
    'contact', // Name of the entity model
    johnDoeId, // ID of the object to retreive
    function (err, johnDoe) { // Returns the fetched object
    console.log('John Doe :', johnDoe); // Should show John Doe
  });
}

Result :

$ node samples/mem-create-get
John Doe id : aa2d2c29-d299-4804-a450-037b49c46672
John Doe : { firstName: 'john',
  lastName: 'doe',
  email: 'john@doe.com',
  vip: true,
  age: 25,
  id: 'aa2d2c29-d299-4804-a450-037b49c46672' }

Datastore API doc

Almost all provided methods are asynchronous, so they accept a callback as last argument, and return a promise.

Lifecycle :

  • new Datastore(opt) : create a datastore instance and, if opt is given, initialize it
  • init(opt) : synchronously initialize the datastore
  • start(opt, cb) : start the datastore (and initialize if needed)
  • stop(cb) : stop the datastore

Options :

Supported options in opt argument used when calling constructor or init() or start() :

  • db : module path [string] or module [object] to require as the db provider
    • Constants for available default providers : Datastore.providers.MEM|REDIS|MONGODB|MYSQL
    • To extend the system : specify your own provider
  • models : models schemas to support
    • key is the entity name
    • value is an object containing all fields to support with types
    • supported types : 'boolean'|'number'|'string'

The others options are related to the specified db provider.

Provider specific options :

  • mem :

    • keyNamespace : namespace to use to store datas in the in-memory map
  • mySQL :

    • host: mySQL server address (default to 'localhost')
    • user: mySQL user to connect with (default to 'root')
    • password : mySQL password to connect with (none by default)
    • database : mySQL database name to use (default to hw-store)
    • full list of options as defined in mysql.createConnection()
  • Redis :

    • host : redis server address (default to '127.0.0.1')
    • port : redis server port (default to 6379)
    • options : redis server options (no options by default)
    • keyNamespace : namespace used as a key prefix in redis
    • full list of options as defined in redis.createClient()
  • MongoDB :

    • host : MongoDB server address (default to 'localhost')
    • port: MongoDB server port (default to 27017)
    • database: name of the database (default to 'hw-store')
    • options: MongoDB server options (default to {safe: true})
    • full list of options as defined in mongoose Connection.open()

Store features :

All features take a collection name as first argument.

CRUD methods :

  • create(name, resource, cb) : save a new resource to collection
  • get(name, id, cb) : fetch a resource by ID
  • update(name, id, resource, cb) : update the resource of given ID
  • del(name, id, cb) : delete the resource from the collection

Extra features :

  • list(name, cb) : fetch the resources of collection
  • purge(name, cb) : remove all the entities in collection
  • find(name, criteria, cb) : find matching resources in collection

Databases support

Currently, following database systems are supported :

Use cases

CRUD with Redis and promises

var Datastore = require('hw-store')
  , store, id;

store = new Datastore({
  db: Datastore.providers.REDIS, // We use a Redis db
  models: { // In our example models contain only one schema
    contact: { // Contact schema
      firstName: 'string',
      lastName: 'string',
      email: 'string',
      vip: 'boolean',
      age: 'number'
    }
  }
});

store.start()
  .then(function () {
    console.log('redis client connected');
  })
  .then(function () {
    return store.create('contact', { // Insert john doe entity
      firstName: 'john',
      lastName: 'doe',
      email: 'john@doe.com',
      vip: true,
      age: 25
    })
  })
  .then(function (entity) {
    console.log('saved entity :', entity);
    id = entity.id; // Get the ID of the new fresh persisted entity
  })
  .then(function () { // Update john doe email and vip properties
    return store.update('contact', id, {email: 'johndoe@example.com', vip: false});
  })
  .then(function () { // Fetch contact by ID
    return store.get('contact', id);
  })
  .then(function (entity) {
    console.log('fetched entity :', entity); // John doe modified
    return store.del('contact', id); // Remove john doe from the store
  })
  .finally(function () {
    return store.stop()
      .then(function () {
        console.log('redis client closed')
      });
  });

Result :

$ node samples/redis-crud-promises
redis client connected
saved entity : { firstName: 'john',
  lastName: 'doe',
  email: 'john@doe.com',
  vip: true,
  age: 25,
  id: 'b487a541-3a5b-40c6-9757-addc25f6dccf' }
fetched entity : { firstName: 'john',
  lastName: 'doe',
  email: 'johndoe@example.com',
  vip: false,
  age: 25,
  id: 'b487a541-3a5b-40c6-9757-addc25f6dccf' }
redis client closed

The same code (except the store configuration) will work for Mongodb and mySQL.

Specify your own provider

To implement a custom provider all you have to do is to provide a factory that returns a subclass of BasicStore with following methods implemented : create, get, update, del, list, purge (optional), find (optional)

This way you can extend the store with a new database system.

Example :

var MyStoreFactory;

MyStoreFactory = function (BasicStore) {
  return createClass('MemStore', {
    parent: BasicStore,
    defaults: {
      config: {
        // Default configuration items
      }
    },
    constructor: function (opt) {
      if (opt) {
        this.init(opt);
      }
    },
    methods: {
      init: function (opt) {
        var that = this;
        that.config = _.extend({}, that.config, opt);
        that.initialized = true;
      },
      start: function (opt, cb) {
        if (typeof cb === 'undefined' && typeof opt === 'function') {
          cb = opt;
          opt = null;
        }
        if (!this.initialized) {
          this.init(opt);
        }
        // start asynchronously
      },
      stop: function (cb) {
        // stop asynchronously
      },
      create: function (name, resource, cb) {
        // save a new resource asynchronously
      },
      get: function (name, id, cb) {
        // fetch a resource asynchronously
      },
      update: function (name, id, resource, cb) {
        // update a resource asynchronously
      },
      del: function (name, id, cb) {
        // delete a resource asynchronously
      },
      list: function (name, cb) {
        // list resources of named collection asynchronously
      }
    }
  });
};

exports = module.exports = MyStoreFactory;

For complete examples look at the default providers

Enjoy !

Readme

Keywords

none

Package Sidebar

Install

npm i hw-store

Weekly Downloads

1

Version

0.0.2

License

MIT

Last publish

Collaborators

  • openhoat