This is a short summary of the solutions for persistent storage that I've found. I've included simple examples of how they would be used. I prefer solutions that support IndexedDb and that have a straightforward mapping in data model.
pouchdb
A couched for browsers. Seams to be the most widespread storage solution for browsers. Storage in IndexedDb is not straight forward. Interacting directly with IndexedDb probably not a good idea.
var db = new PouchDB('kittens');
db.info().then(function (info) {
console.log(info);
});
var doc = {
"_id": "mittens",
"name": "Mittens",
"occupation": "kitten",
"age": 3,
"hobbies": [
"playing with balls of yarn",
"chasing laser pointers",
"lookin' hella cute"
]
};
db.put(doc);
db.get('mittens').then(function (doc) {
console.log(doc);
});
// updates require the full document incl. _rev
db.get('mittens').then(function (doc) {
// update their age
doc.age = 4;
// put them back
return db.put(doc);
}).then(function () {
// fetch mittens again
return db.get('mittens');
}).then(function (doc) {
console.log(doc);
});
alasql
New and inmature solution. Found bugs when using IndexedDb as backend. Re-visit in a while and check for progress. Many open issues in github though.
// data in array
var data = [{a:1,b:10}, {a:2,b:20}, {a:1,b:30}];
var res = alasql('SELECT a, SUM(b) AS b FROM ? GROUP BY a',[data]);
console.log(res);
// data in indexeddb
var cityData = [{city:"Redmond", population:57530},
{city:"Atlanta",population:447841},
{city:"San Fracisco", population:837442}];
alasql('CREATE INDEXEDDB DATABASE IF NOT EXISTS geo');
alasql('CREATE INDEXEDDB DATABASE IF NOT EXISTS geo;\
ATTACH INDEXEDDB DATABASE geo; \
USE geo; \
DROP TABLE IF EXISTS cities; \
CREATE TABLE cities; \
SELECT * INTO cities FROM ?', [cityData], function(){
alasql('SELECT COLUMN * FROM cities WHERE population > 100000 ORDER BY city DESC',
[],function(res){
console.log('Big cities: ', res.join(','));
});
});
NeDB
Mongo type of Api for browsers. No support for IndexedDb.
// Create an in-memory only datastore
var db = new Nedb();
db.insert({ planet: 'Earth' });
db.insert({ planet: 'Mars' });
db.find({}, function (err, docs) {
console.log(docs);
});
// Create a localStorage datastore
var db = new Nedb({filename: 'filename'});
db.insert({ planet: 'Earth' });
db.insert({ planet: 'Mars' });
db.find({}, function (err, docs) {
console.log(docs);
});
dexie.org
Simple wrapper on IndexedDb. Not sure how widely used this is.
var db = new Dexie("FriendDatabase");
db.version(1).stores({
friends: "++id,name,age"
});
db.open();
db.friends.add({name: "Josephine", age: 21}).then(function(){
});
db.friends.where("age").between(20, 30).each(function(friend) {
console.log("Found young friend: " + JSON.stringify(friend));
});
YDN-DB
Not using indexedDb on Safari. Straightforward model for storage in indexeddb (testing with Firefox).
var db = new ydn.db.Storage('yen-db');
db.put('store-name', {message: 'Hello world!'}, 'id1');
db.get('store-name', 'id1').always(function(record) {
console.log(record);
});
localForage
Simple key value store that Mozilla is behind.
var obj = { value: "hello world" };
localforage.setItem('key', obj, function(err, result) { console.log(result.value); });
localforage.getItem('key', function(err, value) { console.log(value) });
TaffyDB
In-memory JavaScript database with support for persistence in localStorage. Has functions for filtering, joining etc.
var friends = TAFFY([
{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"},
{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"},
{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"},
{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"}
]);
friends({city:"Seattle, WA"}).first();
friends.store("taffy");
// reload page
var friends = TAFFY();
friends.store("taffy");
friends({city:"Seattle, WA"}).first();
Summary
The best candidates seams to be PochDb Ydn-db. The drawback with PouchDb is that it is a CouchDb in the browser and the storage model is driven from this. I prefer a simple mapping from documents/JSON to the database I do not need the versioning that Pouch has built in. Ydn-db do not use IndexedDb on Safari, but otherwise this seams like a good candidate. Dexie could also be a candidate even though I'm not sure how widely spread it is.