Skip to content

Instantly share code, notes, and snippets.

@cornedor
Last active December 25, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cornedor/6885601 to your computer and use it in GitHub Desktop.
Save cornedor/6885601 to your computer and use it in GitHub Desktop.
A localStorage database-ish system written in JS
var database = (function () {
'use strict';
var tables = [],
dataCache = {},
toSync = 0,
DEBUG = true;
function log(t) {
if(DEBUG) {
console.log("%c" + t, "color: #090; font-weight: bold;");
}
}
function cacheDatabase(table) {
log("Caching " + table);
var data = JSON.parse(localStorage.getItem(table));
if(data !== null && data !== undefined) {
dataCache[table] = data;
}
}
function count(table) {
return dataCache[table].length;
}
function get(table, id) {
return (dataCache[table] === null || dataCache[table] === undefined) ? undefined : dataCache[table][id];
}
function getByKey(table, key, search) {
var results = [];
if(dataCache[table] === undefined) {
return undefined;
}
for(var i = 0; i < dataCache[table].length; i++) {
if(dataCache[table][i][key] === search) {
results.push(dataCache[table][i]);
}
}
return results;
}
function getAll(table) {
return dataCache[table];
}
function add(table, obj, id) {
if(dataCache[table] === null || dataCache[table] === undefined) {
dataCache[table] = [];
}
if(id === undefined) {
dataCache[table].push(obj);
} else {
dataCache[table][id] = obj;
}
localStorage.setItem(table, JSON.stringify(dataCache[table]));
}
function set(table, id, obj) {
if( dataCache[table] === null ||
dataCache[table] === undefined ||
dataCache[table][id] === null ||
dataCache[table][id] === undefined) {
log("Table [" + table + "] or ID [" + id + "] doesn't exist, using add.");
add(table, obj, id);
} else {
dataCache[table][id] = obj;
localStorage.setItem(table, JSON.stringify(dataCache[table]));
}
}
function remove(table) {
localStorage.removeItem(table);
if(dataCache[table] !== undefined) {
delete dataCache[table];
}
}
function _ajaxSync(table, callbacks) {
$.getJSON(table.url).done(function(data) {
var json = data,
parents,
i = 0;
if(table !== undefined && table.parent !== undefined) {
parents = table.parent.split(".");
for(i = 0; i < parents.length; i++) {
try {
json = json[parents[i]];
} catch(e) {
callbacks.fail(e);
}
}
}
localStorage.setItem(table.name, JSON.stringify(json));
cacheDatabase(table.name);
callbacks.done();
}).fail(function(err) {
console.error(err);
cacheDatabase(table.name);
callbacks.fail(err);
}).always(function() {
callbacks.always();
});
}
function _sync(callbacks, tab) {
log("Doing sync");
var i = 0,
toSync = tab === undefined ? tables.length : tab.length,
syncFailed = false,
singleCallbacks = {
done: function() {
if(toSync === 1 && !syncFailed) {
callbacks.done();
}
},
fail: function() {
syncFailed = true;
callbacks.fail();
},
always: function() {
if(toSync === 1 || syncFailed) {
callbacks.always();
}
toSync--;
}
};
if(tab === undefined) {
for(i = 0; i < tables.length; i++) {
if(tables[i].force === true) {
dataCache[tables[i].name] = [];
}
if(tables[i].url !== undefined) {
_ajaxSync(tables[i], singleCallbacks);
} else {
cacheDatabase(tables[i].name);
singleCallbacks.done();
singleCallbacks.always();
}
}
} else {
for(i = 0; i < tab.length; i++) {
if(tab[i].force === true) {
dataCache[tab[i].name] = [];
}
if(tab[i].url !== undefined) {
_ajaxSync(tab[i], singleCallbacks);
} else {
cacheDatabase(tab[i].name);
singleCallbacks.done();
singleCallbacks.always();
}
}
}
}
function sync() {
var callbacks = {
done: function(){},
fail: function(){},
always: function(){}
},
ret;
setTimeout(function() { _sync(callbacks); });
ret = {
done: function(fun) {
callbacks.done = fun;
return ret;
},
fail: function(fun) {
callbacks.fail = fun;
return ret;
},
always: function(fun) {
callbacks.always = fun;
return ret;
}
};
return ret;
}
function setTables(tab, doSync) {
var callbacks = {
done: function(){},
fail: function(){},
always: function(){}
},
ret;
tables = tables.concat(tab);
if(doSync) {
setTimeout(function(){ _sync(callbacks, tab); });
}
ret = {
done: function(fun) {
callbacks.done = fun;
return ret;
},
fail: function(fun) {
callbacks.fail = fun;
return ret;
},
always: function(fun) {
callbacks.always = fun;
return ret;
}
};
return ret;
}
log("Database loaded");
return {
sync: sync,
cache: cacheDatabase,
count: count,
get: get,
getByKey: getByKey,
getAll: getAll,
dataCache: dataCache,
remove: remove,
add: add,
set: set,
setTables: setTables
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment