Simple Node DB
_____ __ _ __ __ ____
/ __(_)_ _ ___ / /__ / |/ /__ ___/ /__ ___/ / /
_\ \/ / ' \/ _ \/ / -_) / / _ \/ _ / -_) / _ / _ \
/___/_/_/_/_/ .__/_/\__/ /_/|_/\___/\_,_/\__/ \_,_/_.__/
/_/
Overview
A database implementation on top of levelup, leveldown, and memdown. SimpleNodeDb leverages the document store aspects of level up to provide a data-model/domain centric implementation.
Models are stored as JSON strings with domain-scoped keys. For example a user data model's key of '12345' would have an associated domain key of 'user:12345'. So querying for users as opposed to orders or inventory parts is as easy as including records where keys begin with 'user:'.
Automatic model attributes include dateCreated, lastUpdated and version. The version attribute is used to enforce optimistic locking.
Typically SimpleNodeDb is well suited for small to medium datasets (less than 100K rows) or data stores that don't require complex querying. It also provides robust caching when used as an in-memory data store. To support more than 100K rows you should probably create alternate indexing schemes or stick with redis, mongo, or a traditional SQL database.
Note: levelup is a simple key/value store. It may be more appropriate to use this for simple, single user access storage. SimpleNodeDb is designed to work more as a formal domain data store with simulated domains that contain keyed JSON documents. For most use cases, it is more appropriate to use redis or another server based document store if multi-user access is required...
Change Log
0.91.x (requires node 4.x)
- updated levelup, leveldown, memdown, lodash to latest versions
- replaced uuid with ulid, a universally unique lexicographically sortable identifier
- replaced casual with random-fixture-data
- refactored for es6, const/let
Note: Future changes: for now support goes back to node 4.x; the next release will require 6.x to support more es6 features.
Installation
$ npm install simple-node-db --save
Testing And Examples
Basic testing is in place for all implemented methods. Examples can be found under ./examples.
API
constructor
// create an in-memory databaseconst SimpleDb = ;let db = memory:true; // create a file based databasedb = '/path/to/database'; // create a database with optionsconst options = path:'/my/db/path' log:'db' readAfterChange:true // read-back record after insert/update; else return model; db = options ;
query( params, rowCallback, completeCallback )
// query for all list rows where the key begins with 'mydomain:' const rowCallback = { // put appropriate query conditions here if key >= 0 ) // parse and return the value return JSON; }; const completeCallback = { if err throw err; assert listlength === 25}; const params = start:'mydomain:' end:'mydomain:~' // the tilde insures all 'my domain' rows are found; db;
queryKeys( params, completeCallback )
// query for all keys and dump to the console... db;
find( key, callback )
// create the key based on domain and model idconst key = db; // value is saved as a json objectconst callback = { if err throw err; // do something with the model...}; db;
insert( key, model, callback )
// a simple user modelConst user = id:'12345' name:'Sam Sammyson' email:'sam@sammyson.com' status:'active'; // key is created for the 'user' domainconst key = db const callback = { if err throw err; assert modeldateCreated; assert modellastUpdated === modeldateCreated; assert modelversion === 0;}; // model must have an 'id' attributedb;
update( key, model, callback )
// the version and lastUpdated attributes are automatically updatedconst user = id:'12345' dateCreated: lastUpdated: version:0 name:'Sam Sammyson' email:'sam@sammyson.com' status:'active'; const key = db const callback = { if err throw err; assert modelversion === userversion + 1; assert modellastUpdated > userdateCreated;}; // model must have an 'id' attributedb;
delete( key, callback )
// very simple, merciless delete -- use at your own risk...const callback = { if err throw err;}; db;
createModelId()
// create a model id from uuid without dashesconst id = db; assert id === '01BDA6RVHSFRQ2FKZ6FVJPFFSW';
createDomainKey( domain, id );
const model = id:db; const key = db; assert key;assert key; assert key === 'user:01BDA6V2JGXN8WHTSF5DX8H21S';
backup( filename, callback )
// stream dump of keys and values row-by-row, CR/LF delimitedconst filename = '/path/to/backup/file'; const callback = { if err throw err; assert rowsWritten > 0;}; db;
restore( filename, callback )
// read the key/value file and batch put the rows; uses stream reader to const callback = { if err throw err; assert rowsRead > 0;}; const filename = '/path/to/my/backup'; db;
stats( callback )
// reports the domains and number of rows db;
close( callback )
db;
open( callback )
db;
isInMemory()
if db log;
SimpleNodeDb.createREPL( db )
A REPL is available to enable database manipulation from the node repl.
// creates a REPL for SimpleNoeDb and opens the database 'db'// if db is null, then an in-memory db is opened db = ;db // shows the domains, row counts, etcdb // dumps all the rowsdb // dumps all the keysdb // will return the user if it exists // query for all usersdb // or, an alternative to find all the users...let { if key return JSON; };db