Lungo.Data.Sql.js 6.1 KB

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