3.5 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			3.5 KiB
		
	
	
	
	
	
	
	
Master Quest SQLite3
Master Quest is a brave new attempt at Data Mapping.
It kinda looks like an ORM, but it isn't. It's not SQL, it's NoSQL with benefits.
You get to choose which contraints to keep and which to forget.
Guiding Principles
- NoSQL (well, as far as you care)
- Migrations don't suck
- Harness the awesomeness of indexes
- deletedAtto delete a record
- nullto delete a field
- unindexed fields stored as json
- ids should be one either
- deterministic (duplicate records not okay, last updatedAtwins)
- cryptographically random (duplicate records consolidated in application)
 
- deterministic (duplicate records not okay, last 
- avoid mutating data (CRDT-ish style)
- if it won't scale, don't fret it (no foreign key contraints)
- idis simply named- id
- multi-key ids should be sha256sum(key1 + key2 + key3)
- JavaScript is camelCasey, databases aresnake_casey. We can handle that.
- join tables are in alphabet order i.e. foo,bar,bar_foo
TODO / In Progress
- Multi-Master Replication
- Relationships
- currently detaches before saving (most important)
 
- MongoDB / RethinkDB -ish queries
- RealTime
USAGE
npm install --save 'https://github.com/coolaj86/node-masterquest-sqlite3.git'
'use strict';
// works with sqlite3, sqlcipher, and sqlite3-cluster
var db = new (require('sqlite3').Database)('/tmp/data.sqlite3');
require('masterquest-sqlite3').wrap(db, {
  modelname: 'Persons'
, indices: [ 'firstName', 'lastName' ]
, hasMany: [ 'children' ]
}).then(function (mq) {
  // update (or create) deterministic record
  var john = {
    id: 'john.doe@email.com'
  , firstName: 'john'
  , lastName: 'doe'
  , dog: { name: 'ralph', color: 'gold' }
  , children: [ 'stacey@email.com' ]
  };
  mq.Persons.upsert(john.id, john).then(function () {
    // note: if `dog` existed, it will be overwritten, not merged
    // note: `children` will be removed before save
    mq.Persons.get('john.doe@email.com').then(function (data) {
      // dog will be rehydrated from json
      // children will not be fetched and attached
      console.log(data);
    });
  });
});
API
It's kinda CRUDdy... but don't let that scare you.
- upsert(id, data[, oldId])- creates or updates based on existence in DB (use this)- modifies createdAtand orupdatedAt
 
- modifies 
- create(id, obj)- same as above, but fails if the object exists
- save(data[, oldId])- (just don't use this, please) creates or updates based on presence of ID
- destroy(id)- mark a record as- deletedAtfrom DB
- get(id)- grab one by id
- find(attrs, opts)- grab many by indexable attributes- attrs
- explicit nullwill find all (and requires thatlimitbe set)
- { foo: 2, bar: 6 }will find records where- foois- 2and- baris- 6
 
- explicit 
- opts
- orderBy
- orderByDesc
- limit
 
 
- attrs
Schema
Anything that isn't in the schema
- indicesspecifies an array of strings- [ 'firstName', 'lastName' ]
 
- relationships are option and current only exclude during save
- hasMany,- belongsTo,- hasOne,- belongsToMany,- hasAndBelongsToMany
 
- createdAt,- updatedAt,- deletedAttimestamps are always added- turn off with timestamps: false
 
- turn off with 
- idis always- id- change with idname: 'myId'
 
- change with 
Migrations
You can only add indexes. You cannot rename or remove them.
To add an index, simply change the schema.
{ modelname: 'persons'
, indices: [ 'firstName', 'lastName' ]
, hasMany: [ 'children' ]
}
LICENSE
Dual-licensed MIT and Apache-2.0
See LICENSE