slamdb

An ultra-light, ultra-fast, NOT database

Usage no npm install needed!

<script type="module">
  import slamdb from 'https://cdn.skypack.dev/slamdb';
</script>

README

SlamDB

SlamDB is NOT a database. It is a very small, lightweight and fast dataset with optional persistence. I haven't seen any operation take over 50ms working with 100,000 items.

Why?

Simple is better. Especially when it can be easily extended. If you just want a place to store and retrieve data with ease then SlamDB is an excellent choice. If you're looking for something chock-full of features, then I suggest you look at Nedb, TaffyDB, MongoDB, IndexedDB, WebSQL, etc. There are numerous choices.

SlamDB works synchronously. There are no promises, callbacks, etc. Why? Because it's so fast, it doesn't need to be asynchronous.

Installation

In node.js:

npm i slamdb --save

In the browser:

git clone http://github.com/brettof86/slamdb.git
coffee -c index.coffee
cp index.js ~/your/project/path/lib/slamdb.js

Getting Started

If you're working in the browser SlamDB is a window object. If you're working in node.js (including node-webkit) then you use require('slamdb'). From here forward I'll assume you're using Node.js.

The constructor for SlamDB takes one argument that is an object with any of the following fields:

  • localStorage: Value can either be true or a string containing the localStorage key to use.
  • filename: Value is a path to a file which Slam will use to store your data.
  • pk (optional) (defaults to id): Value is the field used as the unique identifier. If you put an item that does not have this field, it will be created and assigned a new integer value. IMPORTANT You cannot use the patch method with an object that doesn't have this property. See more below.
var SlamDB = require('slamdb');

// use a filesystem file (only works with cordova, node and node-webkit)
db = new SlamDB({filename: '/home/users/brett/.mydatastore'});

// filename with node-webkit
var path = require('path');
dataPath = require('nw.gui').App.dataPath;
db = new SlamDB({filename: path.join(dataPath, '.mydatastore')});

// use localStorage ('slamdb' will be used)
db = new SlamDB({localStorage: true});

// use a custom localStorage key
db = new SlamDB({localStorage: 'mydatabase'});

// use a custom field as a unique identifier
db = new SlamDB({localStorage: true, pk: 'path'});

Put (Insert/Update)

In SlamDB inserts and updates are synonymous (think of upsert or the HTTP verb).

Arguments:

  • Object to save
  • Array of items to save

Returns:

  • Object that was put
  • Array if argument was an array

Example:

var myObject = {
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
};

var result = db.put(myObject);

{
    "id": 1,
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
}

If the object you supply does not contain the pk property then an integer will be generated.

Count

Arguments:

  • none

Returns:

  • number representing the total count of items in the dataset

Example:

db.count()

10

All

Arguments:

  • None

Returns:

  • Array containing everything in the set

Example:

db.all();

[{
    "id": 1,
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
},
{
    "id": 2,
    "name": "Angel Joseph",
    "age": 52,
    "address": {
        "line1": "500 Atbif Way",
        "city": "Socnace",
        "state": "AZ"
    }
},
{
    "id": 3,
    "name": "Louise Cook",
    "age": 50,
    "address": {
        "line1": "276 Mujit Street",
        "city": "Ekipubew",
        "state": "FL"
    }
}]

Find

Arguments:

  • string or number that is a unique identifier

Returns:

  • object with the unique identifier
  • null if nothing was found

Example:

db.find(1);

{
    "id": 1,
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
}

Where

Arguments:

  • Object of properties to match
  • or function to defer matches to
    • takes one argument which is one item

Returns:

  • Array of items matching (empty array if none match)

Example:


//
// With `Object` parameter
//
var result = db.where({age: 31});

[{
    "id": 1,
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
},
{
    "id": 2,
    "name": "Angel Joseph",
    "age": 31,
    "address": {
        "line1": "500 Atbif Way",
        "city": "Socnace",
        "state": "AZ"
    }
}
]

//
// With `Function` parameter
//
var result = db.where(function(item){
    return item.age < 50;
});

[{
    "id": 1,
    "name": "Zachary Spencer",
    "age": 31,
    "address": {
        "line1": "1007 Hahlol Trail",
        "city": "Jadhapuj",
        "state": "CO"
    }
},
{
    "id": 4,
    "name": "Jessie Jimenez",
    "age": 38,
    "address": {
        "line1": "335 Wiinu Lane",
        "city": "Ekbuhni",
        "state": "CT"
    }
}
]

First

First is exactly like where, but returns only the first matching item or the first item in the set if no arguments are given.

Arguments:

  • none returns the first item in the dataset
  • or Object of properties to match
  • or function to defer matches to
    • takes one argument which is one item

Returns:

  • Object

Example:

//
// With no parameter
//
var result = db.first();

{
    "id": 0,
    "name": "Roxie Morrison",
    "age": 62,
    "address": {
        "line1": "758 Ehlak Street",
        "city": "Zejsono",
        "state": "AL"
    }
}


//
// With `Object` parameter
//
var result = db.first({age: 62});

{
    "id": 9,
    "name": "Roxie Morrison",
    "age": 62,
    "address": {
        "line1": "758 Ehlak Street",
        "city": "Zejsono",
        "state": "AL"
    }
}


//
// With `Function` parameter
//
var result = db.first(function(item){
    return item.age < 50;
});

{
    "id": 8,
    "name": "Virginia Turner",
    "age": 28,
    "address": {
        "line1": "586 Fezar Key",
        "city": "Onhikul",
        "state": "VT"
    }
}

Last

Last is exactly like where, but returns only the last matching item or the last item in the set if no arguments are given.

Arguments:

  • none returns the last item in the dataset
  • or Object of properties to match
  • or function to defer matches to
    • takes one argument which is one item

Returns:

  • Object

Example:

//
// With no parameter
//
var result = db.last();

{
    "id": 10,
    "name": "Roxie Morrison",
    "age": 62,
    "address": {
        "line1": "758 Ehlak Street",
        "city": "Zejsono",
        "state": "AL"
    }
}


//
// With `Object` parameter
//
var result = db.last({age: 62});

{
    "id": 9,
    "name": "Roxie Morrison",
    "age": 62,
    "address": {
        "line1": "758 Ehlak Street",
        "city": "Zejsono",
        "state": "AL"
    }
}


//
// With `Function` parameter
//
var result = db.last(function(item){
    return item.age < 50;
});

{
    "id": 8,
    "name": "Virginia Turner",
    "age": 28,
    "address": {
        "line1": "586 Fezar Key",
        "city": "Onhikul",
        "state": "VT"
    }
}

Patch

IMPORTANT The argument must contain a pk value or an error will be thrown.

Arguments:

  • Object

Returns:

  • Object that was patched

Example:

var patchObject = {
    "id": 9,
    "name": "Roxie Jefferson"
};

db.patch(patchObject);

{
    "id": 9,
    "name": "Roxie Jefferson"
    "age": 62,
    "address": {
        "line1": "758 Ehlak Street",
        "city": "Zejsono",
        "state": "AL"
    }
}

Destroy

IMPORTANT The argument must contain a pk value or an error will be thrown.

Arguments:

  • Object containing the pk

Returns:

  • nothing

Example:

db.destroy({id: 9});

Reset

Clears the dataset, including the persisted data. IMPORTANT this cannot be undone.

Arguments:

  • none

Returns:

  • nothing

Example:

db.reset();

Q&A

Q: Why can't I use arguments with count?
A: If you want to count items matching criteria then use the where method with length. E.g. db.where({age: 24}).length;

Q: What about limiting the results?
A: Again, use the where method and splice. E.g. db.where({age: 24}).splice(0,10); will get you the first 10 items. Will implementing limits be more efficient? Yes, but not much.

Q: Can I map items?
A: Sure you can

// using Array.prototype.map
db.where({age: 24}).map(function(x){
    return x.age;
});

// using lodash
var items = _.map(db.where({age: 24}), function(x){
    return x.age;
});