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

hw-store

v0.0.2

Published

Persist datas into any store like redis, mongodb, mysql

Downloads

4

Readme

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: '[email protected]',
      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: '[email protected]',
  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: '[email protected]',
      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: '[email protected]', 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: '[email protected]',
  vip: true,
  age: 25,
  id: 'b487a541-3a5b-40c6-9757-addc25f6dccf' }
fetched entity : { firstName: 'john',
  lastName: 'doe',
  email: '[email protected]',
  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 !