/** * Wrapper for using WebSql (HTML5 feature) * * @namespace LUNGO.Data * @class Sql * * @author Javier Jimenez Villar || @soyjavi * @author Guillermo Pascual || @pasku1 */ LUNGO.Data.Sql = (function(lng, undefined) { var CONFIG = { name: 'lungo_db', version: '1.0', size: 65536, schema: [] }; var db = null; /** * Initialize the SQLite storage (HTML5 Feature) * * @method init * * @param {object} Configuration for the Database */ var init = function(db_config) { CONFIG = lng.Core.mix(CONFIG, db_config); db = openDatabase(CONFIG.name, CONFIG.version, CONFIG.name, CONFIG.size); if (db) { _createSchema(); } else { lng.Core.log(3, 'lng.Data.Sql >> Failed to connect to database.'); } }; /** * Select a data set of a given table and based on a selection object * * @method select * * @param {string} Name of the table in the database * @param {object} [OPTIONAL] Object selection condition * @param {Function} Callback when the process is complete */ var select = function(table, where_obj, callback) { var where = (where_obj) ? ' WHERE ' + _convertToSql(where_obj, 'AND') : ''; execute('SELECT * FROM ' + table + where, function(rs) { var result = []; for (var i = 0, len = rs.rows.length; i < len; i++) { result.push(rs.rows.item(i)); } _callbackResponse(callback, result); }); }; /** * Inserts a data set of a given table and based on a data object * * @method insert * * @param {string} Name of the table in the database * @param {object} Data object to insert in table */ var insert = function(table, data_obj) { var fields = ''; var values = ''; for (var field in data_obj) { if (lng.Core.isOwnProperty(data_obj, field)) { var value = data_obj[field]; fields += (fields) ? ', ' + field : field; if (values) values += ', '; values += (isNaN(value)) ? '"' + value + '"' : value; } } execute('INSERT INTO ' + table + ' (' + fields + ') VALUES (' + values + ')'); }; /** * Updates a data set of a given table and based on a data object and * an optional selection object * * @method update * * @param {string} Name of the table in the database * @param {object} Data object to update in table * @param {object} [OPTIONAL] Object selection condition */ var update = function(table, data_obj, where_obj) { var sql = 'UPDATE ' + table + ' SET ' + _convertToSql(data_obj, ','); if (where_obj) sql += ' WHERE ' + _convertToSql(where_obj, 'AND'); execute(sql); }; /** * Delete a data set of a given table and based on a selection object * * @method drop * * @param {string} Name of the table in the database * @param {object} [OPTIONAL] Object selection condition */ var drop = function(table, where_obj) { var where = (where_obj) ? ' WHERE ' + _convertToSql(where_obj, 'AND') : null; execute('DELETE FROM ' + table + where + ';'); }; /** * Executes a SQL statement in the SQLite storage * * @method execute * * @param {string} SQL statement * @param {Function} Callback when the process is complete */ var execute = function(sql, callback) { lng.Core.log(1, 'lng.Data.Sql >> ' + sql); db.transaction(function(tx) { tx.executeSql(sql, [], function(tx, rs) { _callbackResponse(callback, rs); }, _throwError); }); }; var _createSchema = function() { var schema = CONFIG.schema; var schema_len = schema.length; if (!schema_len) return; for (var i = 0; i < schema_len; i++) { var current = schema[i]; _regenerateTable(current); _createTable(current.name, current.fields); } }; var _createTable = function(table, fields) { var sql_fields = ''; for (var field in fields) { if (lng.Core.isOwnProperty(fields, field)) { if (sql_fields) sql_fields += ', '; sql_fields += field + ' ' + fields[field]; } } execute('CREATE TABLE IF NOT EXISTS ' + table + ' (' + sql_fields + ');'); }; var _regenerateTable = function(table) { if (table.drop === true) { _dropTable(table.name); } }; var _dropTable = function(table) { execute('DROP TABLE IF EXISTS ' + table); }; var _convertToSql = function(fields, separator) { var sql = ''; for (var field in fields) { if (lng.Core.isOwnProperty(fields, field)) { var value = fields[field]; if (sql) sql += ' ' + separator + ' '; sql += field + '='; sql += (isNaN(value)) ? '"' + value + '"' : value; } } return sql; }; var _callbackResponse = function(callback, response) { if (lng.Core.toType(callback) === 'function') { setTimeout(callback, 100, response); } }; var _throwError = function(transaction, error) { lng.Core.log(3, 'lng.Data.Sql >> ' + error.code + ': ' + error.message); }; return { init: init, select: select, insert: insert, update: update, drop: drop, execute: execute }; })(LUNGO);