Last active
August 29, 2015 13:56
-
-
Save Loupax/8800449 to your computer and use it in GitHub Desktop.
ClientDB, a library that allows you to emulate db api in the client.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ClientDB = function(){ | |
var DB = this; | |
var localStorage = window.localStorage; | |
// This object will contain an array for every data type | |
var tables = {}; | |
// This object will contain the latest id for every table in the app. | |
var table_ids = {}; | |
// This record will contain any records that are deleted from the local DB, but are not yet synched with the server | |
var deleted_records = {}; | |
// Creates a new record | |
this.insert = function(table_name, row){ | |
tables[table_name] = tables[table_name] || []; | |
row.client_id = getClientId(table_name); | |
tables[table_name].push(row); | |
return row; | |
}; | |
var getClientId = function(table_name){ | |
// Generate the proper client id for the record | |
if(table_ids[table_name]){ | |
table_ids[table_name]++; | |
} | |
else{ | |
table_ids[table_name] = 1; | |
} | |
return table_ids[table_name]; | |
}; | |
// Gets all the records of the provided table that match the contents of the where object | |
this.get = function(table_name, where){ | |
var results = [], current_row, i, table_length, property, match_found; | |
// Gather all the rows in that table that match the properties of the where object | |
if(tables[table_name] && (typeof where === 'object')) | |
{ | |
table_length = tables[table_name].length; | |
for(i = 0; i < table_length; i++) | |
{ | |
current_row = tables[table_name][i]; | |
match_found = true; | |
for(property in where) | |
{ | |
if(!((property in current_row) && (current_row[property] == where[property]))) | |
{ | |
match_found = false; | |
} | |
} | |
if(match_found) | |
{ | |
results.push(current_row); | |
} | |
} | |
return results; | |
} | |
// No where clause is provided? Get everyting | |
if(where === undefined) | |
{ | |
return tables[table_name]; | |
} | |
// If we miss something just return an empty array | |
return []; | |
}; | |
// Remove all the records that match the properties of the where object | |
// from the Client DB | |
this.delete = function(table_name, where){ | |
var records_to_delete = [], current_row, i, table_length, property, match_found, index; | |
// Gather all the rows in that table that match the properties of the where object | |
if(tables[table_name] && (typeof where === 'object')) | |
{ | |
table_length = tables[table_name].length; | |
for(i = 0; i < table_length; i++) | |
{ | |
current_row = tables[table_name][i]; | |
match_found = true; | |
for(property in where) | |
{ | |
if(!((property in current_row) && (current_row[property] == where[property]))) | |
{ | |
match_found = false; | |
} | |
} | |
if(match_found) | |
{ | |
records_to_delete.push(current_row); | |
} | |
} | |
// Remove all the deleted records from the table itself | |
for(i = 0 ; i < records_to_delete.length; i++) | |
{ | |
index = tables[table_name].indexOf(records_to_delete[i]); | |
if(index > -1) | |
{ | |
tables[table_name].splice(index, 1); | |
} | |
} | |
} | |
// No where clause is provided? Delete everyting | |
if(where === undefined) | |
{ | |
records_to_delete = tables[table_name].slice(0); | |
tables[table_name].length = 0; | |
} | |
// After we have gathered all the records that we have deleted, update the global deleted_records object | |
deleted_records[table_name] = deleted_records[table_name] || []; | |
for(i = 0; i < records_to_delete.length; i++) | |
{ | |
deleted_records[table_name].push(records_to_delete[i]); | |
} | |
}; | |
// Synchronises the current db with the one in the server. | |
// | |
// Any records in the client that don't have a server id | |
// will be stored in the database and receive their id | |
// | |
// Any records in the client that have a server id will be | |
// updated in the remote database | |
// | |
// All the records inside the deleted_records object will be | |
// requested to be deleted and removed from the local | |
// db once succesfull. | |
// | |
// When everything is complete, the local storage will be updated | |
// | |
// For this functionality to work, the server must be set up to | |
// receive tables and deleted_records tables, and must respond | |
// with an array that contains all the inserted and updated records | |
// in their current status, and an array containing all the records | |
// that have been succesfully deleted. | |
// Everything will happen in only one request | |
this.sync = function(sync_url, callback){ | |
prepareForSync(); | |
$.post(sync_url, {client_db: tables, deleted_records: deleted_records}, function(response){ | |
tables = (response.records instanceof Array)?{}:response.records; | |
deleted_records = {}; | |
DB.saveToLocalStorage(); | |
},'json').done(function(){ | |
if(callback) | |
{ | |
callback(true); | |
} | |
}).fail(function(){ | |
callback(false); | |
}); | |
}; | |
// Makes sure all the data are valid before syncing with the server | |
var prepareForSync = function(){ | |
var table_name, i, record; | |
for(table_name in tables) | |
{ | |
for(i = 0; i < tables[table_name].length; i++) | |
{ | |
record = tables[table_name][i]; | |
// Set a client id for all the records that don't have one | |
if(record.client_id === null) | |
{ | |
record.client_id = getClientId(table_name); | |
} | |
} | |
} | |
}; | |
// Initializes the localDB with data stored in the local storage | |
this.loadFromLocalStorage = function(){ | |
tables = JSON.parse(localStorage.getItem('tables')) || {}; | |
table_ids = JSON.parse(localStorage.getItem('table_ids')) || {}; | |
deleted_records = JSON.parse(localStorage.getItem('deleted_records')) || {}; | |
}; | |
// Saves the current state of localDb to the local storage | |
this.saveToLocalStorage = function(){ | |
localStorage.setItem('table_ids', JSON.stringify(table_ids)); | |
localStorage.setItem('tables', JSON.stringify(tables)); | |
localStorage.setItem('deleted_records', JSON.stringify(deleted_records)); | |
}; | |
// Does a GET request to the provided URL, and adds the response to the proper table | |
// It should be up to the server to perform security and permission checks | |
this.loadFromRemote = function(table_name, url, callback){ | |
$.get(url, function(response){ | |
console.log(response); | |
var duplicates; | |
for(var i = 0; i < response.length; i++) | |
{ | |
// Is the row already in the local db? If that's so, update the record with the current data | |
duplicates = DB.get(table_name, {id: response[i].id}); | |
if( duplicates.length > 0) | |
{ | |
// Update the record | |
for(var prop in response[i]) | |
{ | |
duplicates[0][prop] = response[i][prop]; | |
} | |
} | |
else | |
// Else, just insert it | |
{ | |
DB.insert(table_name, response[i]); | |
} | |
} | |
if(callback) | |
{ | |
callback(); | |
} | |
},'json'); | |
}; | |
this.init = function(callback){ | |
DB.loadFromLocalStorage(); | |
// Load all the notes. The controller will send only the documents that belong to the currently logged in user | |
}; | |
this.debug = function(){ | |
console.log(tables, table_ids, deleted_records,localStorage); | |
}; | |
this.getTables = function(){ | |
return tables; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment