Lungo.Data.Sql.coffee 4.8 KB

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