Skip to content
simen edited this page Dec 22, 2016 · 10 revisions

1. Overview

objectbox is a dictionary to maintain objects with persistence. objectbox will give you an unique numeric id when your object is added to the dictionary successfully. You can then use this id to find out the object from the box.

objectbox uses NeDB datastore to permanently keep your objects, database is just there by default. If you don't like NeDB, objectbox allows you to use your own persistence facility as the datastore for the objects.


2. Installation

$ npm install objectbox --save


3. Basic Usage

objectbox exports its functionalities as a constructor (Objectbox Class). To create a box, just new an instance from the Objectbox class with input arguments of database and maxNum.

  • The parameter database is the file path to tell NeDB where should your data persist. If you like to use your own database, just let database be your datastore object.
  • The parameter maxNum is optional, you can use it to set the capacity of your box.

Instance of the Objectbox class will be denoted as box in this document, and each object stored in box will be denoted as obj in this document.

Here is an quick example of how to create a box.

var Objectbox = require('objectbox'),
    boxPath = __dirname + '/database/box.db',
    box = new Objectbox(boxPath, 1000);

4. APIs

new Objectbox([database][, maxNum])

Create a new instance from Objectbox class.

Arguments

  1. database (Object | String): objectbox uses NeDB datastore as its default persistence, set database with a file path to tell objectbox where you'd like to keep your data. If this parameter is not given, a dafault path __dirname + '/database/objectbox.db' will be used. If you like to use your own database, this advanced topic: How to use your own database with objectbox will give you some hints.
  2. maxNum (Number): Capacity of the box, which is the maximum number of objs that this box can store. If not given, a default value 65536 will be used.

Returns

  • (Object): box

Example

var Objectbox = require('objectbox'),
    boxPath = __dirname + '/database/box.db',
    
var box = new Objectbox(boxPath, 1000);




.isEmpty()

Checks if this box is empty.

Arguments

  • (None)

Returns

  • (Boolean): Returns true if box is empty, otherwise false.

Example

if (box.isEmpty())
    console.log('There is nothing in the box now.')
else
    console.log('There are some objects in the box.')




.has(id)

Checks if there is an obj with the given id in this box .

Arguments

  1. id (Number): id.

Returns

  • (Boolean): Returns true if there is an obj positioned with the given id, otherwise false.

Example

if (box.has(3)) {
    console.log('There is an obj positioned with id 3 in the box');
}




.get(id)

Get an obj from this box with the given id.

Arguments

  1. id (Number): id.

Returns

  • (Object): Returns the obj if found, otherwise undefined.

Example

var obj = box.get(5);




.getCount()

Get the current number of objs stored in this box.

Arguments

  • (None)

Returns

  • (Number): Current number of objs in the box.

Example

var count = box.getCount(); // 32




.getMaxNum()

Get the maximum number of objs that this box can hold.

Arguments

  • (None)

Returns

  • (Number): Maximum number of objs this box can hold.

Example

var maxNum = box.getMaxNum();   // 1000



.find(predicate)

Iterates over objs in this box, and returns the first obj predicate returns truthy for.

Arguments

  1. predicate (Function): The function invoked per iteration.

Returns

  • (Object): Returns the matched obj, otherwise undefined if not found.

Example

// assume that the following two objs has been stored in the box:
// user1 = { user: 'barney', age: 36, active: true }
// user2 = { user: 'fred', age: 40, active: false }

box.find(function(obj) {        // returns user1
    return obj.age < 40;
});




.findFromDb(query, callback)

Looks for stored objs that matched the query from persistence.

Arguments

  1. query (Object): Query object. Please go to Finding documents for more details if you are using the default NeDB datastore.
  2. callback (Function): function (err, docs) {}. Get called when finding completes.

Returns

  • (None)

Example

// assume that the following two objs has been stored in the box:
// obj1 = { a: '1', b: 2, same: 'hi' }
// obj2 = { x: 0, y: 1, same: 'hi' }

box.findFromDb({ a: '1' }, function (err, docs) {
    // docs will be an array of [ obj1 ]
    console.log(docs);
});

box.findFromDb({ x: 0 }, function (err, docs) {
    // docs will be an array of [ obj2 ]
    console.log(docs);
});

box.findFromDb({ same: 'hi' }, function (err, docs) {
    // docs will be an array of [ obj1, obj2 ]
    console.log(docs);
});




.filter(path[, value])

Iterates over objs in box, and returns an array of objs that predicate returns truthy for.

Arguments

  1. path (String | Function): It can be a direct path of an obj property or a predicate function.
  2. value (Depend): The value to equality check in filtering. This value should be given if path is a string of the direct path to obj propertty.

Returns

  • (Array): Returns the filtered array.

Example

// assume that the following two objs has been stored in the box:
// user1 = { user: 'barney', age: 36, active: true }
// user2 = { user: 'fred', age: 40, active: true }

box.filter(function(obj) {  // returns [ user1 ]
    return obj.age < 40;
});

box.filter('active', true); // returns [ user1, user2 ]




.exportAllIds()

Export all id of objs stored in this box.

Arguments

  • (None)

Returns

  • (Array): Array of ids.

Example

// assume that there are only the following two objs stored in the box:
// obj1 = { a: '1' }, assume that its id is 0
// obj2 = { b: 2 }, assume that its id is 1

box.exportAllObjs();    // [ 0, 1 ]




.exportAllObjs()

Export all objs stored in the box.

Arguments

  • (None)

Returns

  • (Array): Array of objects.

Example

// assume that there are only the following two objs stored in the box:
// obj1 = { a: '1' }, assume that its id is 0
// obj2 = { b: 2 }, assume that its id is 1

box.exportAllObjs();    // [ { a: '1' }, { b: 2 } ]




.set(id, obj, callback)

Store an obj into this box with a specified id. If obj has a synchronous dump() method, the box will invoke it to get the returned data which will be stored in database. This leaves you an opportunity to decide what kind of data you'd like to store in database. If obj does not has a dump() method, it will be stringified by NeDB and be stored in database.

Arguments

  1. id (Number): The id specified for which obj you'd like to store.
  2. obj (Object): obj to be stored.
  3. callback (Function): function (err, id) {}. Get called after stored. Error occurs if id conflicts.

Returns

  • (None)

Example

var obj1 = {
        id: null,
        x: 0,
        y: 1,
        z: 2
    },
    obj2 = {
        id: null,
        a: 0,
        b: 1,
        c: 2,
        info: { name: 'obj2', props: [ 'a', 'b', 'c' ] }
        dump: function () {
            return this.info;
        }
    }

box.set(1, obj1, function (err, id) {
    if (err) {
        console.log(err)
    } else {
        // id equals to 1, and obj1 will be stored to database
        obj1.id = id;   // you can assign the got id to obj1 for it to track where itself is in the box  
    }
});

box.set(2, obj2, function (err, id) {
    if (err) {
        console.log(err)
    } else {
        // id equals to 2, and obj2.dump() output will be stored to database
        obj2.id = id;
    }
});




.add(obj, callback)

Store an obj to the box. If obj has a synchronous dump() method, the box will invoke it to get the returned data which will be stored in database. This leaves you an opportunity to decide what kind of data you'd like to store in database. If obj does not has a dump() method, it will be stringified by NeDB and be stored in database.

If obj.dump() output data or obj itself has an property id, the box will try to store the obj with its intrinsic id. Otherwise, the box will return a new id for this newly stored obj.

Arguments

  1. obj (Object): obj to store.
  2. callback (Function): function (err, id) {}. Get called when stored. Error occurs if the box if full or id conflicts.

Returns

  • (None)

Example

var obj = {
        x: 0,
        y: 1,
        z: 2
    };

box.add(obj, function (err, id) {
    if (err)
        console.log(err)
    else
        obj.id = id;
});




.remove(id, callback)

Remove an obj with specified id from box, and its record in database will also be deleted.

Arguments

  1. id (Number): id.
  2. callback (Function): function (err, id) {}. Get called when removal completes. Error occurs if removal fails.

Returns

  • (None)

Example

box.remove(3, function (err) {
    if (err)
        console.log(err);
    else
        console.log('Removal succeeds.');
});




.removeElement(id)

Remove an obj with the specified id from box, but keeps its data in database.

Arguments

  1. id (Number): id.

Returns

  • (Boolean): Returns true if successfully removed. Returns false if removal fails or there is nothing to be removed (no obj positioned at given id in the dictionary).

Example

// assume that the following two obj has been stored in the box:
// obj1 = { a: '1' }, and its id is 60

if (box.removeElement(60))
    console.log('Removal succeeds.');

if (!box.removeElement(60))
    console.log('Remove agagin, removal fails.');




.modify(id, path, snippet, callback)

Modify a certain snippet of obj with the given direct path.

Arguments

  1. id (Number): id.
  2. path (String): Path of the snippet to modify.
  3. snippet (Depends): The snippet to modify. If snippet is an object, the target will be partially updated.
  4. callback (Function): function (err, diffSnippet) {}. Get called when modification succeeds.

Returns

  • (None)

Example

// assume that the following two obj has been stored in the box:
// obj = {
//           x: 'hi', y: 11,
//           z: { z1: 'hello', z2: false, z3: 0 }
//       }
// , and its id is 27

box.modify(27, 'x', 'hello', function (err, diffSnippet) {
    if (err) {
        console.log(err);
    } else {
        console.log(diffSnippet);
        /*
        diffSnippet equals to { x: 'hello' }
        object data in database is now updated to 
        {
            x: 'hello',
            y: 11,
            z: {
                z1: 'hello',
                z2: false,
                z3: 0
            }
        }
        */
    }

    box.modify(27, 'z.z2', true, function (err, diffSnippet) {
        if (err) {
            console.log(err);
        } else {
            console.log(diffSnippet);
            /*
            diffSnippet equals to { z: { z2: true }}
            object data in database is now updated to 
            {
                x: 'hello',
                y: 11,
                z: {
                    z1: 'hello',
                    z2: true,
                    z3: 0
                }
            }
            */
        }

        box.modify(27, 'z.z4', 1, function (err, diffSnippet) {
            // If the path of obj does not exist, an error will occur.
            if (err) {
                console.log(err);
                // err equal to [Error: No such property z.z4 to modify.]
            }
        });
    });
});




.replace(id, path, value, callback)

Replace a new value at the given direct path of obj.

Arguments

  1. id (Number): id.
  2. path (String): Path of the property value to replace.
  3. value (Depends): The value to replace.
  4. callback (Function): function (err, numReplaced) {}. Get called when replacement succeeds.

Returns

  • (None)

Example

// assume that the following two obj has been stored in the box:
// obj = {
//           x: 'hi', y: 11,
//           z: { z1: 'hello', z2: false, z3: 0 }
//       }
// , and its id is 27

box.replace(27, 'x', 'hello', function (err, numReplaced) {
    if (err) {
        console.log(err);
    } else {
        console.log(numReplaced);
        /*
        numReplaced equals to 1
        obj data in database is updated to 
        {
            x: 'hello',
            y: 11,
            z: {
                z1: 'hello',
                z2: false,
                z3: 0
            }
        }
        */
    }

    box.replace(27, 'z.z2', true, function (err, numReplaced) {
        if (err) {
            console.log(err);
        } else {
            console.log(numReplaced);
            /*
            numReplaced equals to 1
            obj data in database is updated to 
            {
                x: 'hello',
                y: 11,
                z: {
                    z1: 'hello',
                    z2: true,
                    z3: 0
                }
            }
            */
        }

        box.replace(27, 'z.z4', 1, function (err, numReplaced) {
            // If the path of obj does not exist, an error will occur.
            if (err) {
                console.log(err);
                // err equal to [Error: No such property z.z4 to replace.]
            }
        });

        box.replace(27, 'z', { z11: 'hi', z2: true }, function (err, numReplaced) {
            if (err) {
                console.log(err);
            } else {
                console.log(numReplaced);
                /*
                numReplaced equals to 1
                obj data in database is updated to 
                {
                    x: 'hi',
                    y: 11,
                    z: {
                        z11: 'hi',
                        z2: true
                    }
                }
                */
            }
        });
    });
});




.sync(id, callback)

Sync the specified obj between box and database.

Arguments

  1. id (Number): id.
  2. callback (Function): function (err) {}. Get called when synchronization succeeds.

Returns

  • (None)

Example

box.sync(1, function (err) {
    if (err)
        console.log(err); 
});




.maintain(callback)

Maintain and sync the obj data between box and database. At first, the box will check for those objs exist in database but not in box. Those objs found at this step will be deleted from database. Finally, each obj in box will dump itself to database again.

Arguments

  1. callback (Function): Get called when maintenance completes.

Returns

  • (None)

Example

box.maintain(function (err) {
    if (err)
        console.log(err); 
});



5. Advanced Topic

How to use your own database with objectbox

To use your own datastore, you can create a box like this:

var box = new Objectbox(db, 1000);

where db is an object on behalf of a datastore. You should make sure that the following methods are provided by db object:




.insert(doc, callback)

Insert a document to the datastore. This method should make sure that if the document already exists in the datastore. If it does, use new document to update the old one.

Note: Each doc has a property id which is unique in the box, you can use property id to determine whether data already exists.

Arguments

  1. doc (Object): The document, which is an data object to be persisted.
  2. callback (Function): function (err, newDoc) {}. This callback should be called when doc is inserted to datastore.

Returns

  • (None)




.removeById(id, callback)

Remove a document from datastore by the given id.

Arguments

  1. id (Number): id.
  2. callback (Function): function (err, newDoc) {}. Should be called when the document is removed from datastore.

Returns

  • (None)




.findById(id, callback)

Find a document from datastore by the given id.

Arguments

  1. id (Number): id.
  2. callback (Function): function (err, newDoc) {}. Should be called when finding completes.

Returns

  • (None)




.modify(id, path, snippet, callback)

Modify a snippet in the document with the given path.

Arguments

  1. id (Number): id.
  2. path (String): Path of the property to modify.
  3. snippet (Depends): The snippet to modify.
  4. callback (Function): function (err, diffSnippet) {}. Should be called when modification completes.

Returns

  • (None)




.replace(id, path, value, callback)

Replace a value in the document with the given path.

Arguments

  1. id (Number): id.
  2. path (String): Path of the property to replace.
  3. value (Depends): The value to replace.
  4. callback (Function): function (err, numReplaced) {}. Should be called when replacement completes.

Returns

  • (None)




.findAll(callback)

Get all documents stored in the datastore.

Arguments

  1. callback (Function): function (err, docs) { }. Should be called with all documents.

Returns

  • (None)




.find(query, callback)

It is a NeDB find method, which follows the MongoDB find behavior. You should provide this method on your datastore with the same behavior for objectbox. (It would be cool if you are using MongoDB as the datastore, you just don't have to implement this method.)

Arguments

  1. query (Object): The query object.
  2. callback (Function): function (err, docs) {}. Should be called when finding docs completes.

Returns

  • (None)