diff --git a/src/providers/websql.js b/src/providers/websql.js index 721b775..4101de1 100644 --- a/src/providers/websql.js +++ b/src/providers/websql.js @@ -4,6 +4,7 @@ define(function(require) { var WSQL_VERSION = require('src/constants').WSQL_VERSION; var WSQL_SIZE = require('src/constants').WSQL_SIZE; var WSQL_DESC = require('src/constants').WSQL_DESC; + var u8toArray = require('src/shared').u8toArray; function WebSQLContext(db, isReadOnly) { var that = this; @@ -27,7 +28,7 @@ define(function(require) { callback(null); } this.getTransaction(function(transaction) { - transaction.executeSql("DELETE FROM " + FILE_STORE_NAME, + transaction.executeSql("DELETE FROM " + FILE_STORE_NAME + ";", [], onSuccess, onError); }); }; @@ -35,17 +36,37 @@ define(function(require) { function onSuccess(transaction, result) { // If the key isn't found, return null var value = result.rows.length === 0 ? null : result.rows.item(0).data; - callback(null, value); + try { + if(value) { + value = JSON.parse(value); + // Deal with special-cased flattened typed arrays in WebSQL (see put() below) + if(value.__isUint8Array) { + value = new Uint8Array(value.__array); + } + } + callback(null, value); + } catch(e) { + callback(e); + } } function onError(transaction, error) { callback(error); } this.getTransaction(function(transaction) { - transaction.executeSql("SELECT data FROM " + FILE_STORE_NAME + " WHERE id = ?", + transaction.executeSql("SELECT data FROM " + FILE_STORE_NAME + " WHERE id = ?;", [key], onSuccess, onError); }); }; WebSQLContext.prototype.put = function(key, value, callback) { + // We do extra work to make sure typed arrays survive + // being stored in the db and still get the right prototype later. + if(Object.prototype.toString.call(value) === "[object Uint8Array]") { + value = { + __isUint8Array: true, + __array: u8toArray(value) + }; + } + value = JSON.stringify(value); function onSuccess(transaction, result) { callback(null); } @@ -53,7 +74,7 @@ define(function(require) { callback(error); } this.getTransaction(function(transaction) { - transaction.executeSql("INSERT OR REPLACE INTO " + FILE_STORE_NAME + " (id, data) VALUES (?, ?)", + transaction.executeSql("INSERT OR REPLACE INTO " + FILE_STORE_NAME + " (id, data) VALUES (?, ?);", [key, value], onSuccess, onError); }); }; @@ -65,7 +86,7 @@ define(function(require) { callback(error); } this.getTransaction(function(transaction) { - transaction.executeSql("DELETE FROM " + FILE_STORE_NAME + " WHERE id = ?", + transaction.executeSql("DELETE FROM " + FILE_STORE_NAME + " WHERE id = ?;", [key], onSuccess, onError); }); }; @@ -113,9 +134,15 @@ define(function(require) { [], gotCount, onError); } + // Create the table and index we'll need to store the fs data. db.transaction(function(transaction) { - transaction.executeSql("CREATE TABLE IF NOT EXISTS " + FILE_STORE_NAME + " (id unique, data)", - [], onSuccess, onError); + function createIndex(transaction) { + transaction.executeSql("CREATE INDEX IF NOT EXISTS idx_" + FILE_STORE_NAME + "_id" + + " on " + FILE_STORE_NAME + " (id);", + [], onSuccess, onError); + } + transaction.executeSql("CREATE TABLE IF NOT EXISTS " + FILE_STORE_NAME + " (id unique, data TEXT);", + [], createIndex, onError); }); }; WebSQL.prototype.getReadOnlyContext = function() { diff --git a/src/shared.js b/src/shared.js index a98d1d4..16d9439 100644 --- a/src/shared.js +++ b/src/shared.js @@ -15,9 +15,22 @@ define(function(require) { function nop() {} + /** + * Convert a Uint8Array to a regular array + */ + function u8toArray(u8) { + var array = []; + var len = u8.length; + for(var i = 0; i < len; i++) { + array[i] = u8[i]; + } + return array; + } + return { guid: guid, hash: hash, + u8toArray: u8toArray, nop: nop };