GearsStorageProvider.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. if (!dojo._hasResource["dojox.storage.GearsStorageProvider"]) { // _hasResource
  2. // checks added
  3. // by build. Do
  4. // not use
  5. // _hasResource
  6. // directly in
  7. // your code.
  8. dojo._hasResource["dojox.storage.GearsStorageProvider"] = true;
  9. dojo.provide("dojox.storage.GearsStorageProvider");
  10. dojo.require("dojox.storage.Provider");
  11. dojo.require("dojox.storage.manager");
  12. dojo.require("dojox.sql");
  13. if (dojo.isGears) {
  14. (function() {
  15. // make sure we don't define the gears provider if we're not gears
  16. // enabled
  17. dojo.declare("dojox.storage.GearsStorageProvider",
  18. dojox.storage.Provider, {
  19. // summary:
  20. // Storage provider that uses the features of Google
  21. // Gears
  22. // to store data (it is saved into the local SQL
  23. // database
  24. // provided by Gears, using dojox.sql)
  25. // description:
  26. //
  27. //
  28. // You can disable this storage provider with the
  29. // following djConfig
  30. // variable:
  31. // var djConfig = { disableGearsStorage: true };
  32. //
  33. // Authors of this storage provider-
  34. // Brad Neuberg, bkn3@columbia.edu
  35. constructor : function() {
  36. },
  37. // instance methods and properties
  38. TABLE_NAME : "__DOJO_STORAGE",
  39. initialized : false,
  40. _available : null,
  41. initialize : function() {
  42. // console.debug("dojox.storage.GearsStorageProvider.initialize");
  43. if (djConfig["disableGearsStorage"] == true) {
  44. return;
  45. }
  46. // partition our storage data so that multiple apps
  47. // on the same host won't collide
  48. this.TABLE_NAME = "__DOJO_STORAGE";
  49. // create the table that holds our data
  50. try {
  51. dojox.sql("CREATE TABLE IF NOT EXISTS "
  52. + this.TABLE_NAME + "( "
  53. + " namespace TEXT, " + " key TEXT, "
  54. + " value TEXT " + ")");
  55. dojox
  56. .sql("CREATE UNIQUE INDEX IF NOT EXISTS namespace_key_index"
  57. + " ON "
  58. + this.TABLE_NAME
  59. + " (namespace, key)");
  60. } catch (e) {
  61. console
  62. .debug(
  63. "dojox.storage.GearsStorageProvider.initialize:",
  64. e);
  65. this.initialized = false; // we were unable to
  66. // initialize
  67. dojox.storage.manager.loaded();
  68. return;
  69. }
  70. // indicate that this storage provider is now loaded
  71. this.initialized = true;
  72. dojox.storage.manager.loaded();
  73. },
  74. isAvailable : function() {
  75. // is Google Gears available and defined?
  76. return this._available = dojo.isGears;
  77. },
  78. put : function(key, value, resultsHandler, namespace) {
  79. if (this.isValidKey(key) == false) {
  80. throw new Error("Invalid key given: " + key);
  81. }
  82. namespace = namespace || this.DEFAULT_NAMESPACE;
  83. // serialize the value;
  84. // handle strings differently so they have better
  85. // performance
  86. if (dojo.isString(value)) {
  87. value = "string:" + value;
  88. } else {
  89. value = dojo.toJson(value);
  90. }
  91. // try to store the value
  92. try {
  93. dojox
  94. .sql(
  95. "DELETE FROM "
  96. + this.TABLE_NAME
  97. + " WHERE namespace = ? AND key = ?",
  98. namespace, key);
  99. dojox.sql("INSERT INTO " + this.TABLE_NAME
  100. + " VALUES (?, ?, ?)",
  101. namespace, key, value);
  102. } catch (e) {
  103. // indicate we failed
  104. console
  105. .debug(
  106. "dojox.storage.GearsStorageProvider.put:",
  107. e);
  108. resultsHandler(this.FAILED, key, e.toString());
  109. return;
  110. }
  111. if (resultsHandler) {
  112. resultsHandler(dojox.storage.SUCCESS, key, null);
  113. }
  114. },
  115. get : function(key, namespace) {
  116. if (this.isValidKey(key) == false) {
  117. throw new Error("Invalid key given: " + key);
  118. }
  119. namespace = namespace || this.DEFAULT_NAMESPACE;
  120. // try to find this key in the database
  121. var results = dojox.sql("SELECT * FROM "
  122. + this.TABLE_NAME
  123. + " WHERE namespace = ? AND "
  124. + " key = ?", namespace, key);
  125. if (!results.length) {
  126. return null;
  127. } else {
  128. results = results[0].value;
  129. }
  130. // destringify the content back into a
  131. // real JavaScript object;
  132. // handle strings differently so they have better
  133. // performance
  134. if (dojo.isString(results)
  135. && (/^string:/.test(results))) {
  136. results = results.substring("string:".length);
  137. } else {
  138. results = dojo.fromJson(results);
  139. }
  140. return results;
  141. },
  142. getNamespaces : function() {
  143. var results = [dojox.storage.DEFAULT_NAMESPACE];
  144. var rs = dojox.sql("SELECT namespace FROM "
  145. + this.TABLE_NAME
  146. + " DESC GROUP BY namespace");
  147. for (var i = 0; i < rs.length; i++) {
  148. if (rs[i].namespace != dojox.storage.DEFAULT_NAMESPACE) {
  149. results.push(rs[i].namespace);
  150. }
  151. }
  152. return results;
  153. },
  154. getKeys : function(namespace) {
  155. namespace = namespace || this.DEFAULT_NAMESPACE;
  156. if (this.isValidKey(namespace) == false) {
  157. throw new Error("Invalid namespace given: "
  158. + namespace);
  159. }
  160. var rs = dojox
  161. .sql( "SELECT key FROM "
  162. + this.TABLE_NAME
  163. + " WHERE namespace = ?",
  164. namespace);
  165. var results = [];
  166. for (var i = 0; i < rs.length; i++) {
  167. results.push(rs[i].key);
  168. }
  169. return results;
  170. },
  171. clear : function(namespace) {
  172. if (this.isValidKey(namespace) == false) {
  173. throw new Error("Invalid namespace given: "
  174. + namespace);
  175. }
  176. namespace = namespace || this.DEFAULT_NAMESPACE;
  177. dojox
  178. .sql( "DELETE FROM " + this.TABLE_NAME
  179. + " WHERE namespace = ?",
  180. namespace);
  181. },
  182. remove : function(key, namespace) {
  183. namespace = namespace || this.DEFAULT_NAMESPACE;
  184. dojox.sql("DELETE FROM " + this.TABLE_NAME
  185. + " WHERE namespace = ? AND"
  186. + " key = ?", namespace, key);
  187. },
  188. putMultiple : function(keys, values, resultsHandler,
  189. namespace) {
  190. if (this.isValidKeyArray(keys) === false
  191. || !values instanceof Array
  192. || keys.length != values.length) {
  193. throw new Error("Invalid arguments: keys = ["
  194. + keys + "], values = [" + values + "]");
  195. }
  196. if (namespace == null
  197. || typeof namespace == "undefined") {
  198. namespace = dojox.storage.DEFAULT_NAMESPACE;
  199. }
  200. if (this.isValidKey(namespace) == false) {
  201. throw new Error("Invalid namespace given: "
  202. + namespace);
  203. }
  204. this._statusHandler = resultsHandler;
  205. // try to store the value
  206. try {
  207. dojox.sql.open();
  208. dojox.sql.db.execute("BEGIN TRANSACTION");
  209. var _stmt = "REPLACE INTO " + this.TABLE_NAME
  210. + " VALUES (?, ?, ?)";
  211. for (var i = 0; i < keys.length; i++) {
  212. // serialize the value;
  213. // handle strings differently so they have
  214. // better performance
  215. var value = values[i];
  216. if (dojo.isString(value)) {
  217. value = "string:" + value;
  218. } else {
  219. value = dojo.toJson(value);
  220. }
  221. dojox.sql.db.execute(_stmt, [namespace,
  222. keys[i], value]);
  223. }
  224. dojox.sql.db.execute("COMMIT TRANSACTION");
  225. dojox.sql.close();
  226. } catch (e) {
  227. // indicate we failed
  228. console
  229. .debug(
  230. "dojox.storage.GearsStorageProvider.putMultiple:",
  231. e);
  232. if (resultsHandler) {
  233. resultsHandler(this.FAILED, keys, e
  234. .toString());
  235. }
  236. return;
  237. }
  238. if (resultsHandler) {
  239. resultsHandler(dojox.storage.SUCCESS, key, null);
  240. }
  241. },
  242. getMultiple : function(keys, namespace) {
  243. // TODO: Maybe use SELECT IN instead
  244. if (this.isValidKeyArray(keys) === false) {
  245. throw new ("Invalid key array given: " + keys);
  246. }
  247. if (namespace == null
  248. || typeof namespace == "undefined") {
  249. namespace = dojox.storage.DEFAULT_NAMESPACE;
  250. }
  251. if (this.isValidKey(namespace) == false) {
  252. throw new Error("Invalid namespace given: "
  253. + namespace);
  254. }
  255. var _stmt = "SELECT * FROM " + this.TABLE_NAME
  256. + " WHERE namespace = ? AND " + " key = ?";
  257. var results = [];
  258. for (var i = 0; i < keys.length; i++) {
  259. var result = dojox.sql(_stmt, namespace,
  260. keys[i]);
  261. if (!result.length) {
  262. results[i] = null;
  263. } else {
  264. result = result[0].value;
  265. // destringify the content back into a
  266. // real JavaScript object;
  267. // handle strings differently so they have
  268. // better performance
  269. if (dojo.isString(result)
  270. && (/^string:/.test(result))) {
  271. results[i] = result
  272. .substring("string:".length);
  273. } else {
  274. results[i] = dojo.fromJson(result);
  275. }
  276. }
  277. }
  278. return results;
  279. },
  280. removeMultiple : function(keys, namespace) {
  281. namespace = namespace || this.DEFAULT_NAMESPACE;
  282. dojox.sql.open();
  283. dojox.sql.db.execute("BEGIN TRANSACTION");
  284. var _stmt = "DELETE FROM " + this.TABLE_NAME
  285. + " WHERE namespace = ? AND key = ?";
  286. for (var i = 0; i < keys.length; i++) {
  287. dojox.sql.db.execute(_stmt,
  288. [namespace, keys[i]]);
  289. }
  290. dojox.sql.db.execute("COMMIT TRANSACTION");
  291. dojox.sql.close();
  292. },
  293. isPermanent : function() {
  294. return true;
  295. },
  296. getMaximumSize : function() {
  297. return this.SIZE_NO_LIMIT;
  298. },
  299. hasSettingsUI : function() {
  300. return false;
  301. },
  302. showSettingsUI : function() {
  303. throw new Error(this.declaredClass
  304. + " does not support a storage settings user-interface");
  305. },
  306. hideSettingsUI : function() {
  307. throw new Error(this.declaredClass
  308. + " does not support a storage settings user-interface");
  309. }
  310. });
  311. // register the existence of our storage providers
  312. dojox.storage.manager.register(
  313. "dojox.storage.GearsStorageProvider",
  314. new dojox.storage.GearsStorageProvider());
  315. dojox.storage.manager.initialize();
  316. })();
  317. }
  318. }