hw-store
v0.0.2
Published
Persist datas into any store like redis, mongodb, mysql
Downloads
4
Readme
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 !