Lungo.Data.Sql.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * Wrapper for using WebSql (HTML5 feature)
  3. *
  4. * @namespace Lungo.Data
  5. * @class Sql
  6. *
  7. * @author Javier Jimenez Villar <javi@tapquo.com> || @soyjavi
  8. * @author Guillermo Pascual <pasku@tapquo.com> || @pasku1
  9. */
  10. Lungo.Data.Sql = (function(lng, undefined) {
  11. var ERROR = lng.Constants.ERROR;
  12. var CONFIG = {
  13. name: 'lungo_db',
  14. version: '1.0',
  15. size: 65536,
  16. schema: []
  17. };
  18. var db = null;
  19. /**
  20. * Initialize the SQLite storage (HTML5 Feature)
  21. *
  22. * @method init
  23. *
  24. * @param {object} Configuration for the Database
  25. */
  26. var init = function(db_config) {
  27. CONFIG = lng.Core.mix(CONFIG, db_config);
  28. db = openDatabase(CONFIG.name, CONFIG.version, CONFIG.name, CONFIG.size);
  29. if (db) {
  30. _createSchema();
  31. } else {
  32. throw new Error(ERROR.DATABASE);
  33. }
  34. };
  35. /**
  36. * Select a data set of a given table and based on a selection object
  37. *
  38. * @method select
  39. *
  40. * @param {string} Name of the table in the database
  41. * @param {object} [OPTIONAL] Object selection condition
  42. * @param {Function} Callback when the process is complete
  43. */
  44. var select = function(table, where_obj, callback) {
  45. var where = (where_obj) ? ' WHERE ' + _convertToSql(where_obj, 'AND') : '';
  46. execute('SELECT * FROM ' + table + where, function(rs) {
  47. var result = [];
  48. for (var i = 0, len = rs.rows.length; i < len; i++) {
  49. result.push(rs.rows.item(i));
  50. }
  51. _callbackResponse(callback, result);
  52. });
  53. };
  54. /**
  55. * Inserts a data set of a given table and based on a data object
  56. *
  57. * @method insert
  58. *
  59. * @param {string} Name of the table in the database
  60. * @param {object} Object (or Array of objects) to insert in table
  61. */
  62. var insert = function(table, data, callback) {
  63. if (lng.Core.toType(data) === 'object') {
  64. _insertRow(table, data);
  65. } else {
  66. for (row in data) {
  67. _insertRow(table, data[row]);
  68. }
  69. }
  70. };
  71. /**
  72. * Updates a data set of a given table and based on a data object and
  73. * an optional selection object
  74. *
  75. * @method update
  76. *
  77. * @param {string} Name of the table in the database
  78. * @param {object} Data object to update in table
  79. * @param {object} [OPTIONAL] Object selection condition
  80. */
  81. var update = function(table, data_obj, where_obj, callback) {
  82. var sql = 'UPDATE ' + table + ' SET ' + _convertToSql(data_obj, ',');
  83. if (where_obj) sql += ' WHERE ' + _convertToSql(where_obj, 'AND');
  84. execute(sql);
  85. };
  86. /**
  87. * Delete a data set of a given table and based on a selection object
  88. *
  89. * @method drop
  90. *
  91. * @param {string} Name of the table in the database
  92. * @param {object} [OPTIONAL] Object selection condition
  93. */
  94. var drop = function(table, where_obj, callback) {
  95. var where = (where_obj) ? ' WHERE ' + _convertToSql(where_obj, 'AND') : '';
  96. execute('DELETE FROM ' + table + where + ';');
  97. };
  98. /**
  99. * Executes a SQL statement in the SQLite storage
  100. *
  101. * @method execute
  102. *
  103. * @param {string} SQL statement
  104. * @param {Function} Callback when the process is complete
  105. */
  106. var execute = function(sql, callback) {
  107. lng.Core.log(1, 'lng.Data.Sql >> ' + sql);
  108. db.transaction( function(transaction) {
  109. transaction.executeSql(sql, [], function(transaction, rs) {
  110. _callbackResponse(callback, rs);
  111. }, function(transaction, error) {
  112. transaction.executedQuery = sql;
  113. _throwError.apply(null, arguments);
  114. });
  115. });
  116. };
  117. var _createSchema = function() {
  118. var schema = CONFIG.schema;
  119. var schema_len = schema.length;
  120. if (!schema_len) return;
  121. for (var i = 0; i < schema_len; i++) {
  122. var current = schema[i];
  123. _regenerateTable(current);
  124. _createTable(current.name, current.fields);
  125. }
  126. };
  127. var _createTable = function(table, fields) {
  128. var sql_fields = '';
  129. for (var field in fields) {
  130. if (lng.Core.isOwnProperty(fields, field)) {
  131. if (sql_fields) sql_fields += ', ';
  132. sql_fields += field + ' ' + fields[field];
  133. }
  134. }
  135. execute('CREATE TABLE IF NOT EXISTS ' + table + ' (' + sql_fields + ');');
  136. };
  137. var _regenerateTable = function(table) {
  138. if (table.drop === true) {
  139. _dropTable(table.name);
  140. }
  141. };
  142. var _dropTable = function(table) {
  143. execute('DROP TABLE IF EXISTS ' + table);
  144. };
  145. var _convertToSql = function(fields, separator) {
  146. var sql = '';
  147. for (var field in fields) {
  148. if (lng.Core.isOwnProperty(fields, field)) {
  149. var value = fields[field];
  150. if (sql) sql += ' ' + separator + ' ';
  151. sql += field + '=';
  152. sql += (isNaN(value)) ? '"' + value + '"' : value;
  153. }
  154. }
  155. return sql;
  156. };
  157. var _callbackResponse = function(callback, response) {
  158. if (lng.Core.toType(callback) === 'function') {
  159. setTimeout(callback, 100, response);
  160. }
  161. };
  162. var _insertRow = function(table, row) {
  163. var fields = '';
  164. var values = '';
  165. for (var field in row) {
  166. if (lng.Core.isOwnProperty(row, field)) {
  167. var value = row[field];
  168. fields += (fields) ? ', ' + field : field;
  169. if (values) values += ', ';
  170. values += (isNaN(value) || value=='') ? '"' + value + '"' : value;
  171. }
  172. }
  173. execute('INSERT INTO ' + table + ' (' + fields + ') VALUES (' + values + ')');
  174. };
  175. var _throwError = function(transaction, error) {
  176. throw new Error(ERROR.DATABASE_TRANSACTION + error.code + ': ' + error.message + ' \n Executed query: ' + transaction.executedQuery);
  177. };
  178. return {
  179. init: init,
  180. select: select,
  181. insert: insert,
  182. update: update,
  183. drop: drop,
  184. execute: execute
  185. };
  186. })(Lungo);