source: Dev/trunk/src/client/dojox/storage/GearsStorageProvider.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

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