2.3.13 • Published 2 years ago

symdb v2.3.13

Weekly downloads
2
License
MIT
Repository
github
Last release
2 years ago

symdb

A JSON database that uses symbolic links for indexing

reasoning

There are a lot of JSON databases available on npm. Of the ones I investigated, most store the objects for a collection in a single json file. Upon loading a collection, the whole json file is loaded in to memory. While this is probably the fastest method for accessing and updating objects in a collection, it could be problematic for large collections. It also does not really lend itself to replication in an easy way.

goals

  • Use the filesystem
    • each object should be stored in their own .json file
    • directories and symbolic links should be used for indexing

example

const SymDb = require('symdb');

const db = new SymDb({ root : './db' });

const Product = db.Model('product', {
    product_id : Number
    , name : String
    , description : String
    , type : String
});

async function go() {
    let obj = await Product.add({
        product_id : 1
        , name : 'Test'
        , type : 'test-product'
    });

    //you'll notice that the object now has a ._id attribute that is a uuid
    console.log(obj); 

    let results = await Product.get({ type : 'test-product' });

    //results is an array of objects whose type value is 'test-product'
    console.log(results);
}

go();

api

symdb = new SymDb(opts)

  • opts.root - string - the path to the root directory in which database files should be stored

Model = symdb.Model(name, schema)

  • name - string - the name of the model/collection
  • schema - object - an object which contains key:Type pairs
    • the Types are generally, String, Number, or some other function that will format the value to how you want it indexed.
    • NOTE: this is not thoroughly tested and needs love

Model.get(lookup, context) => Promise

let results = Model.get({
    weight : SymDb.gt(42)
});

// also these
SymDb.gt(10)
SymDb.gte(10)
SymDb.lt(9)
SymDb.lte(9)
SymDb.startsWith('bart')
SymDb.contains('bart')
SymDb.between(1, 10)
SymDb.contains(['a','b', 'c'])
SymDb.compare(function (z) { return z === 1234 })

Model.getSync(lookup, context) => Array

Model.add(obj, context) => Promise

Model.addSync(obj, context) => Object

Model.update(obj, context) => Promise

Model.updateSync(obj, context) => Object

Model.del(obj, context) => Promise

Model.delSync(obj, context) => Object

Model Events

Example:

Model.on('update:before', (event, cb) => {
    //cb must be called when done;

    event.data.password = null;

    return cb();
});

Callback with an error to prevent the operation from continuing

Model.on('add:before', (event, cb) => {
    if (!event.user.canAdd) {
        return cb(new Error('user does not have add permissions'));
    }

    return cb();
});

try {
    let obj = await Model.add({ href : 'https://www.google.com' }, { user : { canAdd : false } });
}
catch (e) {
    //should have thrown 'user does not have add permissions'
}

Model.on('get:before', (event, cb) => {})

Model.on('get:after', (event, cb) => {})

Model.on('get-sync:before', (event, cb) => {})

Model.on('get-sync:after', (event, cb) => {})

Model.on('add:before', (event, cb) => {})

Model.on('add:after', (event, cb) => {})

Model.on('add-sync:before', (event, cb) => {})

Model.on('add-sync:after', (event, cb) => {})

Model.on('update:before', (event, cb) => {})

Model.on('update:after', (event, cb) => {})

Model.on('update-sync:before', (event, cb) => {})

Model.on('update-sync:after', (event, cb) => {})

Model.on('delete:before', (event, cb) => {})

Model.on('delete:after', (event, cb) => {})

Model.on('delete-sync:before', (event, cb) => {})

Model.on('delete-sync:after', (event, cb) => {})

Model.on('save:before', (event, cb) => {})

Model.on('save:after', (event, cb) => {})

Model.on('save-sync:before', (event, cb) => {})

Model.on('save-sync:after', (event, cb) => {})

todo

  • docs
  • wildcard lookups
  • case-insensitive lookups
  • range lookups
  • lookups on non-indexed attributes
  • deep attribute indexing
  • fulltext search
  • fix cleanup of empty index directories
  • rewrite .update() handling to not call delete() then save()
  • paging
  • sorting
  • https://github.com/davedoesdev/getdents
  • automatic blob storage (Buffers, ReadStreams, SymDbFile)
    • Buffers
    • Readable Streams
    • SymDbFile (a wrapper around a long string to be stored in a file outside of the json object)
    • need to handle deleting blobs on update:before
    • toggle blobs on/off per db/model
  • change on-disk format to have a wrapping json object that contains metadata
    • does the object have blobs?
    • if so, which keys?
    • keep symbolic links references in the metadata?
  • synchronous versions of all model operations

license

MIT

2.3.13

2 years ago

2.3.12

2 years ago

2.3.11

3 years ago

2.3.8

3 years ago

2.3.9

3 years ago

2.3.10

3 years ago

2.3.7

4 years ago

2.3.3

4 years ago

2.3.1

4 years ago

2.3.0

4 years ago

2.2.1

4 years ago

2.2.0

4 years ago

2.1.3

5 years ago

2.1.2

5 years ago

1.9.2

5 years ago

2.1.1

5 years ago

2.0.0

5 years ago

1.9.1

5 years ago

1.9.0

5 years ago

1.8.0

5 years ago

1.7.1

5 years ago

1.7.0

5 years ago

1.6.2

5 years ago

1.6.1

5 years ago

1.6.0

5 years ago

1.5.0

6 years ago

1.4.0

6 years ago

1.3.2

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.0

6 years ago

1.1.0

6 years ago

1.0.2

6 years ago