Permalink
Browse files

Draft. Including test suits from w3c-test.org/webapps/IndexedDB/tests…

…/submissions/Microsoft/

and making them run.
  • Loading branch information...
1 parent 134aa1a commit 197f158ad2fa3f03d7d2b9d8c91b71d50434b4f0 Khamza Davletov committed Jul 7, 2012
Showing with 5,413 additions and 292 deletions.
  1. +108 −47 IDBCursor.js
  2. +4 −12 IDBDatabase.js
  3. +5 −7 IDBFactory.js
  4. +2 −4 IDBIndex.js
  5. +38 −2 IDBKeyRange.js
  6. +74 −76 IDBObjectStore.js
  7. +2 −2 IDBRequest.js
  8. +18 −2 IDBTransaction.js
  9. +12 −0 README
  10. +1 −16 index.html
  11. +144 −124 indexedDB.polyfill.js → indexedDB.init.js
  12. +36 −0 indexedDB.polyfill.debug.js
  13. +28 −0 w3c-tests/Microsoft/idb_webworkers.htm
  14. +73 −0 w3c-tests/Microsoft/idbcursor_advance_index.htm
  15. +69 −0 w3c-tests/Microsoft/idbcursor_advance_objectstore.htm
  16. +66 −0 w3c-tests/Microsoft/idbcursor_continue_index.htm
  17. +62 −0 w3c-tests/Microsoft/idbcursor_continue_index2.htm
  18. +62 −0 w3c-tests/Microsoft/idbcursor_continue_index3.htm
  19. +63 −0 w3c-tests/Microsoft/idbcursor_continue_index4.htm
  20. +63 −0 w3c-tests/Microsoft/idbcursor_continue_objectstore.htm
  21. +60 −0 w3c-tests/Microsoft/idbcursor_continue_objectstore2.htm
  22. +61 −0 w3c-tests/Microsoft/idbcursor_continue_objectstore3.htm
  23. +60 −0 w3c-tests/Microsoft/idbcursor_continue_objectstore4.htm
  24. +72 −0 w3c-tests/Microsoft/idbcursor_delete_index.htm
  25. +63 −0 w3c-tests/Microsoft/idbcursor_delete_index2.htm
  26. +61 −0 w3c-tests/Microsoft/idbcursor_delete_index3.htm
  27. +70 −0 w3c-tests/Microsoft/idbcursor_delete_objectstore.htm
  28. +60 −0 w3c-tests/Microsoft/idbcursor_delete_objectstore2.htm
  29. +58 −0 w3c-tests/Microsoft/idbcursor_delete_objectstore3.htm
  30. +76 −0 w3c-tests/Microsoft/idbcursor_update_index.htm
  31. +67 −0 w3c-tests/Microsoft/idbcursor_update_index2.htm
  32. +63 −0 w3c-tests/Microsoft/idbcursor_update_index3.htm
  33. +71 −0 w3c-tests/Microsoft/idbcursor_update_objectstore.htm
  34. +62 −0 w3c-tests/Microsoft/idbcursor_update_objectstore2.htm
  35. +60 −0 w3c-tests/Microsoft/idbcursor_update_objectstore3.htm
  36. +47 −0 w3c-tests/Microsoft/idbdatabase_close.htm
  37. +44 −0 w3c-tests/Microsoft/idbdatabase_close2.htm
  38. +37 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore.htm
  39. +39 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore2.htm
  40. +43 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore3.htm
  41. +45 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore4.htm
  42. +37 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore5.htm
  43. +45 −0 w3c-tests/Microsoft/idbdatabase_createObjectStore6.htm
  44. +42 −0 w3c-tests/Microsoft/idbdatabase_deleteObjectStore.htm
  45. +48 −0 w3c-tests/Microsoft/idbdatabase_deleteObjectStore2.htm
  46. +42 −0 w3c-tests/Microsoft/idbdatabase_deleteObjectStore3.htm
  47. +42 −0 w3c-tests/Microsoft/idbdatabase_transaction.htm
  48. +43 −0 w3c-tests/Microsoft/idbdatabase_transaction2.htm
  49. +47 −0 w3c-tests/Microsoft/idbdatabase_transaction3.htm
  50. +27 −0 w3c-tests/Microsoft/idbfactory_cmp.htm
  51. +35 −0 w3c-tests/Microsoft/idbfactory_deleteDatabase.htm
  52. +35 −0 w3c-tests/Microsoft/idbfactory_deleteDatabase2.htm
  53. +33 −0 w3c-tests/Microsoft/idbfactory_open.htm
  54. +37 −0 w3c-tests/Microsoft/idbfactory_open2.htm
  55. +46 −0 w3c-tests/Microsoft/idbfactory_open3.htm
  56. +35 −0 w3c-tests/Microsoft/idbfactory_open4.htm
  57. +36 −0 w3c-tests/Microsoft/idbfactory_open5.htm
  58. +42 −0 w3c-tests/Microsoft/idbfactory_open6.htm
  59. +40 −0 w3c-tests/Microsoft/idbfactory_open7.htm
  60. +35 −0 w3c-tests/Microsoft/idbfactory_open8.htm
  61. +47 −0 w3c-tests/Microsoft/idbindex_count.htm
  62. +14 −0 w3c-tests/Microsoft/idbworker.js
  63. +57 −0 w3c-tests/Microsoft/support.js
  64. +91 −0 w3c-tests/testharness.css
  65. +1,928 −0 w3c-tests/testharness.js
  66. +380 −0 w3c-tests/testharnessreport.js
View
155 IDBCursor.js
@@ -6,52 +6,110 @@ if (window.indexedDB.polyfill)
this.source = source;
this.direction = direction || IDBCursor.NEXT;
this.key = null; // position
- this.primaryKey = null; // effective key, object store position
+ this.primaryKey = null; // effective key
this._request = request;
this._range = null;
this._gotValue = true;
+ this._effectiveKey = null;
};
IDBCursor.prototype.update = function (value)
{
-
+ var objectStore = getObjectStore(this);
+ IDBTransaction._assertNotReadOnly(objectStore.transaction);
+ if (!(this instanceof util.IDBCursorWithValue) || !this._gotValue) throw util.error("InvalidStateError");
+ if (objectStore.keyPath != null)
+ {
+ var key = util.extractKeyFromValue(objectStore.keyPath, value);
+ if (key != this.primaryKey) throw util.error("DataError");
+ }
+ var request = new util.IDBRequest(this);
+ var me = this;
+ objectStore.transaction._enqueueRequest(function (sqlTx, nextRequestCallback)
+ {
+ objectStore._insertOrReplaceRecord(
+ {
+ request : request,
+ sqlTx : sqlTx,
+ nextRequestCallback : nextRequestCallback,
+ noOverwrite : false,
+ value : value
+ },
+ me._effectiveKey);
+ });
+ return request;
};
IDBCursor.prototype.advance = function (count)
{
+ count = parseInt(count);
+ if (isNaN(count) || count <= 0) throw util.error("TypeError");
+ advanceOrContinue(this, count, null);
};
IDBCursor.prototype.continue = function (key)
{
- if (!this._gotValue) throw util.error("InvalidStateError");
- this._gotValue = false;
+ advanceOrContinue(this, 1, key);
+ };
+
+ IDBCursor.prototype.delete = function ()
+ {
+ var objectStore = getObjectStore(this);
+ IDBTransaction._assertNotReadOnly(objectStore.transaction);
+ if (!(this instanceof util.IDBCursorWithValue) || !this._gotValue) throw util.error("InvalidStateError");
+
+ var request = new util.IDBRequest(this);
+ var me = this;
+ objectStore.transaction._enqueueRequest(function (sqlTx, nextRequestCallback)
+ {
+ objectStore._deleteRecord(sqlTx, me._effectiveKey,
+ function ()
+ {
+ if (request.onsuccess) request.onsuccess(util.event("success", request));
+ nextRequestCallback();
+ },
+ function (_, sqlError)
+ {
+ request.error = sqlError;
+ if (request.onerror) request.onerror(util.event("error", request));
+ nextRequestCallback();
+ });
+ });
+ return request;
+ };
+
+ // Internal methods
+ function advanceOrContinue(me, count, key)
+ {
+ if (!me._gotValue) throw util.error("InvalidStateError");
+ me._gotValue = false;
- var range = this._range;
- var filter = util.IDBKeyRange.bound(range.lower, range.upper, range.lowerOpen, range.upperOpen);
- var isIndex = this.source instanceof util.IDBIndex;
- var position = this.key;
- var noDuplicate = [IDBCursor.PREV_NO_DUPLICATE, IDBCursor.NEXT_NO_DUPLICATE].indexOf(this.direction) >= 0;
+ var filter = util.IDBKeyRange._clone(me._range);
+ filter.count = count;
+ var isSourceIndex = me.source instanceof util.IDBIndex;
+ var position = me.key;
+ var noDuplicate = [IDBCursor.PREV_NO_DUPLICATE, IDBCursor.NEXT_NO_DUPLICATE].indexOf(me.direction) >= 0;
if (key != null)
{
- if (isDesc(this))
+ if (isDesc(me))
{
- if ((isIndex && key > position) || key >= position) throw util.error("DataError");
+ if ((isSourceIndex && key > position) || key >= position) throw util.error("DataError");
filter.upper = key;
filter.upperOpen = false;
}
else
{
- if ((isIndex && key < position) || key <= position) throw util.error("DataError");
+ if ((isSourceIndex && key < position) || key <= position) throw util.error("DataError");
filter.lower = key;
filter.lowerOpen = false;
}
}
else if (position != null)
{
- var open = !isIndex || noDuplicate;
- if (isDesc(this))
+ var open = !isSourceIndex || noDuplicate;
+ if (isDesc(me))
{
filter.upper = position;
filter.upperOpen = open;
@@ -62,22 +120,10 @@ if (window.indexedDB.polyfill)
filter.lowerOpen = open;
}
}
- if (isIndex)
- {
- iterateIndexCursor(this, filter);
- }
- else
- {
- iterateCursor(this, filter);
- }
- };
-
- IDBCursor.prototype.delete = function ()
- {
-
- };
+ if (isSourceIndex) iterateIndexCursor(me, filter);
+ else iterateCursor(me, filter);
+ }
- // Internal methods
function iterateCursor(me, filter)
{
var tx = me.source.transaction;
@@ -87,12 +133,12 @@ if (window.indexedDB.polyfill)
var sql = ["SELECT key, value FROM [" + me.source.name + "]"];
var where = [];
var args = [];
- if (filter.lower)
+ if (filter.lower != null)
{
where.push("(key >" + (filter.lowerOpen ? "" : "=") + " ?)");
args.push(w_JSON.stringify(filter.lower));
}
- if (filter.upper)
+ if (filter.upper != null)
{
where.push("(key <" + (filter.upperOpen ? "" : "=") + " ?)");
args.push(w_JSON.stringify(filter.upper));
@@ -101,22 +147,24 @@ if (window.indexedDB.polyfill)
{
sql.push("WHERE", where.join(" AND "))
}
- sql.push("ORDER BY key" + (isDesc(me) ? " DESC" : ""), "LIMIT 1");
+ sql.push("ORDER BY key" + (isDesc(me) ? " DESC" : ""));
+ sql.push("LIMIT", filter.count);
sqlTx.executeSql(sql.join(" "), args,
function (tx, results)
{
var request = me._request;
request.readyState = util.IDBRequest.DONE;
- if (results.rows.length == 0)
+ if (results.rows.length < filter.count)
{
- me.key = me.primaryKey = undefined;
+ me.key = me.primaryKey = me._effectiveKey = undefined;
if (typeof me.value !== "undefined") me.value = undefined;
request.result = null;
}
else
{
- var found = results.rows.item(0);
+ var found = results.rows.item(filter.count - 1);
+ me._effectiveKey = found.key;
me.key = me.primaryKey = w_JSON.parse(found.key);
if (typeof me.value !== "undefined") me.value = w_JSON.parse(found.value);
me._gotValue = true;
@@ -152,8 +200,8 @@ if (window.indexedDB.polyfill)
{
sql.push("LEFT JOIN [" + objectStoreName + "] as t ON t.Id = i.recordId");
}
- var where = [], args = [], strPrimaryKey = null;
- if (filter.lower)
+ var where = [], args = [];
+ if (filter.lower != null)
{
var strLower = w_JSON.stringify(filter.lower);
args.push(strLower);
@@ -163,19 +211,18 @@ if (window.indexedDB.polyfill)
}
else
{
- if (me.primaryKey == null || desc)
+ if (me._effectiveKey == null || desc)
{
where.push("(i.key >= ?)");
}
else
{
where.push("((i.key > ?) OR (i.key = ? AND i.primaryKey > ?))");
- strPrimaryKey = w_JSON.stringify(me.primaryKey);
- args.push(strLower, strPrimaryKey);
+ args.push(strLower, me._effectiveKey);
}
}
}
- if (filter.upper)
+ if (filter.upper != null)
{
var strUpper = w_JSON.stringify(filter.upper);
args.push(strUpper);
@@ -185,14 +232,14 @@ if (window.indexedDB.polyfill)
}
else
{
- if (me.primaryKey == null || !desc)
+ if (me._effectiveKey == null || !desc)
{
where.push("(i.key <= ?)");
}
else
{
where.push("((i.key < ?) OR (i.key = ? AND i.primaryKey < ?))");
- args.push(strUpper, strPrimaryKey || w_JSON.stringify(me.primaryKey));
+ args.push(strUpper, me._effectiveKey);
}
}
}
@@ -201,23 +248,25 @@ if (window.indexedDB.polyfill)
sql.push("WHERE", where.join(" AND "))
}
var sDesc = desc ? " DESC" : "";
- sql.push("ORDER BY i.key" + sDesc + ", i.primaryKey" + sDesc + " LIMIT 1");
+ sql.push("ORDER BY i.key" + sDesc + ", i.primaryKey" + sDesc);
+ sql.push("LIMIT", filter.count);
sqlTx.executeSql(sql.join(" "), args,
function (tx, results)
{
var request = me._request;
request.readyState = util.IDBRequest.DONE;
- if (results.rows.length == 0)
+ if (results.rows.length < filter.count)
{
- me.key = me.primaryKey = undefined;
+ me.key = me.primaryKey = me._effectiveKey = undefined;
if (typeof me.value !== "undefined") me.value = undefined;
request.result = null;
}
else
{
- var found = results.rows.item(0);
+ var found = results.rows.item(filter.count - 1);
me.key = w_JSON.parse(found.key);
+ me._effectiveKey = found.primaryKey;
me.primaryKey = w_JSON.parse(found.primaryKey);
if (typeof me.value !== "undefined") me.value = w_JSON.parse(found.value);
me._gotValue = true;
@@ -244,6 +293,18 @@ if (window.indexedDB.polyfill)
return [IDBCursor.PREV, IDBCursor.PREV_NO_DUPLICATE].indexOf(cursor.direction) >= 0;
}
+ function getObjectStore(cursor)
+ {
+ if (cursor.source instanceof util.IDBObjectStore)
+ {
+ return cursor.source;
+ }
+ else if (cursor.source instanceof util.IDBIndex)
+ {
+ return cursor.source.objectStore;
+ }
+ return null;
+ }
IDBCursor.NEXT = "next";
IDBCursor.NEXT_NO_DUPLICATE = "nextunique";
View
16 IDBDatabase.js
@@ -12,12 +12,12 @@ if (window.indexedDB.polyfill)
this._webdb = webdb;
this._objectStores = null;
+ this._closePending = false;
};
IDBDatabase.prototype.createObjectStore = function (name, optionalParameters)
{
- validateVersionChangeTx(this._versionChangeTx);
-
+ IDBTransaction._assertVersionChange(this._versionChangeTx);
// Validate existence of ObjectStore
if (this.objectStoreNames.indexOf(name) >= 0)
{
@@ -38,7 +38,7 @@ if (window.indexedDB.polyfill)
IDBDatabase.prototype.deleteObjectStore = function (name)
{
var tx = this._versionChangeTx;
- validateVersionChangeTx(tx);
+ IDBTransaction._assertVersionChange(tx);
if (this.objectStoreNames.indexOf(name) == -1)
{
throw util.error("NotFoundError");
@@ -69,7 +69,7 @@ if (window.indexedDB.polyfill)
IDBDatabase.prototype.close = function ()
{
- return null;
+ this._closePending = true;
};
IDBDatabase.prototype._loadObjectStores = function (sqlTx, successCallback, errorCallback)
@@ -114,14 +114,6 @@ if (window.indexedDB.polyfill)
// Utils
var w_JSON = window.JSON;
- function validateVersionChangeTx(tx)
- {
- if (!tx || tx.mode !== util.IDBTransaction.VERSION_CHANGE)
- {
- throw util.error("InvalidStateError");
- }
- }
-
function createObjectStore(me, name, keyPath, autoIncrement)
{
var objectStore = new util.IDBObjectStore(name, keyPath, autoIncrement, me._versionChangeTx);
View
12 IDBFactory.js
@@ -135,23 +135,21 @@ if (window.indexedDB.polyfill)
indexedDB.deleteDatabase = function (name)
{
// INFO: There is no way to delete database in Web SQL Database API.
- var request = new util.IDBOpenDBRequest();
- request.readyState = util.IDBRequest.LOADING;
+ var request = new util.IDBOpenDBRequest(null);
indexedDB.util.async(function()
{
request.readyState = util.IDBRequest.DONE;
var sqldb = openSqlDB(name);
if (sqldb.version == "")
{
- if (request.onsuccess) request.onsuccess(null);
+ if (request.onsuccess) request.onsuccess(util.event("success", request));
}
else
{
sqldb.changeVersion(sqldb.version, "",
- function (tx)
+ function (sqlTx)
{
-
- tx.executeSql("SELECT a.type, a.name, b.name 'table' FROM " + indexedDB.SCHEMA_TABLE +
+ sqlTx.executeSql("SELECT a.type, a.name, b.name 'table' FROM " + indexedDB.SCHEMA_TABLE +
" a LEFT JOIN " + indexedDB.SCHEMA_TABLE + " b ON a.type = 'index' AND a.tableId = b.Id",
null,
function (tx, results)
@@ -172,7 +170,7 @@ if (window.indexedDB.polyfill)
},
function ()
{
- if (request.onsuccess) request.onsuccess(null);
+ if (request.onsuccess) request.onsuccess(util.event("success", request));
});
}
});
View
6 IDBIndex.js
@@ -17,8 +17,7 @@ if (window.indexedDB.polyfill)
var request = new util.IDBRequest(this);
request.readyState = util.IDBRequest.LOADING;
var cursor = new util.IDBCursorWithValue(this, direction, request);
-
- cursor._range = util.IDBKeyRange.ensureKeyRange(range);
+ cursor._range = util.IDBKeyRange._ensureKeyRange(range);
cursor.continue();
return request;
};
@@ -28,8 +27,7 @@ if (window.indexedDB.polyfill)
var request = new util.IDBRequest(this);
request.readyState = util.IDBRequest.LOADING;
var cursor = new util.IDBCursor(this, direction, request);
-
- cursor._range = util.IDBKeyRange.ensureKeyRange(range);
+ cursor._range = util.IDBKeyRange._ensureKeyRange(range);
cursor.continue();
return request;
};
View
40 IDBKeyRange.js
@@ -29,7 +29,7 @@ if (window.indexedDB.polyfill)
return new IDBKeyRange(lower, upper, lowerOpen || false, upperOpen || false);
};
- IDBKeyRange.ensureKeyRange = function (arg)
+ IDBKeyRange._ensureKeyRange = function (arg)
{
if (arg == null)
{
@@ -40,6 +40,42 @@ if (window.indexedDB.polyfill)
return arg;
}
return util.IDBKeyRange.only(arg);
- }
+ };
+
+ IDBKeyRange._clone = function (range)
+ {
+ return util.IDBKeyRange.bound(range.lower, range.upper, range.lowerOpen, range.upperOpen);
+ };
+
+ IDBKeyRange.prototype._getSqlFilter = function (keyColumnName)
+ {
+ if (keyColumnName == undefined) keyColumnName = "key";
+
+ var sql = [], args = [];
+ var hasLower = this.lower != null, hasUpper = this.upper != null;
+
+ if (hasLower && hasUpper && !this.lowerOpen && !this.upperOpen)
+ {
+ sql.push("(key = ?)");
+ args = [this.lower];
+ }
+ else
+ {
+ if (hasLower)
+ {
+ sql.push("(key >" + (this.lowerOpen ? "" : "=") + " ?)");
+ args.push(w_JSON.stringify(this.lower));
+ }
+ if (hasUpper)
+ {
+ sql.push("(key <" + (this.upperOpen ? "" : "=") + " ?)");
+ args.push(w_JSON.stringify(this.upper));
+ }
+ }
+ return { sql : sql.join(" AND "), args : args };
+ };
+
+ // Utils
+ var w_JSON = window.JSON;
}(window, window.indexedDB.util));
View
150 IDBObjectStore.js
@@ -26,7 +26,7 @@ if (window.indexedDB.polyfill)
//region add & put helper functions
function storeRecord(me, value, key, noOverwrite)
{
- assertReadOnly(me.transaction);
+ util.IDBTransaction._assertNotReadOnly(me.transaction);
var validation = validateObjectStoreKey(me.keyPath, me.autoIncrement, value, key);
var key = validation.key, strKey = validation.str;
@@ -52,7 +52,7 @@ if (window.indexedDB.polyfill)
{
if (key != null) throw util.error("DataError");
- key = extractKeyFromValue(value, keyPath);
+ key = util.extractKeyFromValue(keyPath, value);
}
if (key == null)
{
@@ -78,32 +78,6 @@ if (window.indexedDB.polyfill)
return false;
}
- function extractKeyFromValue(value, keyPath)
- {
- var key, i;
- if (keyPath instanceof Array)
- {
- key = [];
- for (i = 0; i < keyPath.length; i++)
- {
- key.push(extractKeyFromValue(value, keyPath[i]));
- }
- }
- else
- {
- if (keyPath === "") return value;
-
- key = value;
- var paths = keyPath.split(".");
- for (i = 0; i < paths.length; i++)
- {
- if (key == null) return null;
- key = key[paths[i]];
- }
- }
- return key;
- }
-
function runStepsForStoringRecord(context, key, strKey)
{
var request = context.request;
@@ -134,7 +108,7 @@ if (window.indexedDB.polyfill)
incrementCurrentNumber(sqlTx, me.name, Math.floor(key + 1));
}
context.sqlTx = sqlTx;
- sqlInsertKeyValue(context, strKey);
+ me._insertOrReplaceRecord(context, strKey);
},
function (_, sqlError)
{
@@ -145,7 +119,7 @@ if (window.indexedDB.polyfill)
}
else
{
- sqlInsertKeyValue(context, strKey);
+ me._insertOrReplaceRecord(context, strKey);
}
}
@@ -182,33 +156,10 @@ if (window.indexedDB.polyfill)
}
- function sqlInsertKeyValue(context, strKey)
- {
- var request = context.request;
- var sql = (context.noOverwrite ? "INSERT" : "REPLACE") + " INTO \"" +
- request.source.name + "\" (key, value) VALUES (?, ?)";
-
- context.primaryKey = strKey;
- var strValue = w_JSON.stringify(context.value);
- context.sqlTx.executeSql(sql, [strKey, strValue],
- function (sqlTx, results)
- {
- context.sqlTx = sqlTx;
- context.recordId = results.insertId;
- storeIndexes(context);
- },
- function (sqlTx, sqlError)
- {
- request.error = sqlError;
- if (request.onerror) request.onerror(util.event("error", request));
- context.nextRequestCallback();
- });
- }
-
function storeIndexes(context)
{
var request = context.request;
- var me = request.source;
+ var me = context.objectStore;
var indexes = [], strKeys = [];
for (var indexName in me._indexes)
{
@@ -239,7 +190,7 @@ if (window.indexedDB.polyfill)
function getValidIndexKeyString(index, value)
{
- var key = extractKeyFromValue(value, index.keyPath);
+ var key = util.extractKeyFromValue(index.keyPath, value);
if (key == null) return null;
if (key instanceof Array)
@@ -307,23 +258,25 @@ if (window.indexedDB.polyfill)
IDBObjectStore.prototype.delete = function (key)
{
- assertReadOnly(this.transaction);
+ util.IDBTransaction._assertNotReadOnly(this.transaction);
+ if (!(key instanceof util.IDBKeyRange)) throw util.error("DataError");
+ var strKey = w_JSON.stringify(key);
+ if (notValidKey(strKey)) throw util.error("DataError");
- var request = new util.IDBRequest();
- request.source = this;
+ var request = new util.IDBRequest(this);
var me = this;
this.transaction._enqueueRequest(function (sqlTx, nextRequestCallback)
{
- var strKey = w_JSON.stringify(key);
- sqlTx.executeSql("DELETE FROM \"" + me.name + "\" WHERE key = ?", [strKey],
- function (_, results)
+ me._deleteRecord(sqlTx, strKey,
+ function ()
{
if (request.onsuccess) request.onsuccess(util.event("success", request));
nextRequestCallback();
},
function (_, sqlError)
{
- if (request.onerror) request.onerror(sqlError);
+ request.error = sqlError;
+ if (request.onerror) request.onerror(util.event("error", request));
nextRequestCallback();
});
});
@@ -369,14 +322,14 @@ if (window.indexedDB.polyfill)
request.readyState = util.IDBRequest.LOADING;
var cursor = new util.IDBCursorWithValue(this, direction, request);
- cursor._range = util.IDBKeyRange.ensureKeyRange(range);
+ cursor._range = util.IDBKeyRange._ensureKeyRange(range);
cursor.continue();
return request;
};
IDBObjectStore.prototype.createIndex = function (name, keyPath, optionalParameters)
{
- validateVersionChangeTx(this.transaction);
+ util.IDBTransaction._assertVersionChange(this.transaction);
if (this.indexNames.indexOf(name) >= 0)
{
throw util.error("ConstraintError");
@@ -409,7 +362,7 @@ if (window.indexedDB.polyfill)
IDBObjectStore.prototype.deleteIndex = function (indexName)
{
- validateVersionChangeTx(this.transaction);
+ util.IDBTransaction._assertVersionChange(this.transaction);
if (this.indexNames.indexOf(indexName) == -1)
{
throw util.error("ConstraintError");
@@ -438,24 +391,69 @@ if (window.indexedDB.polyfill)
{
};
- // Utils
- var w_JSON = window.JSON;
-
- function assertReadOnly(tx)
+ IDBObjectStore.prototype._deleteRecord = function (sqlTx, strKeyOrRange, onsuccess, onerror)
{
- if (tx.mode === util.IDBTransaction.READ_ONLY)
+ var objectStore = this;
+ var sql, where, args = [];
+ if (strKeyOrRange instanceof util.IDBKeyRange)
{
- throw util.error("ReadOnlyError", "A mutation operation was attempted in a READ_ONLY transaction.");
+ var filter = strKeyOrRange._getSqlFilter();
+ where = "WHERE " + filter.sql;
+ args = filter.args;
}
- }
+ else
+ {
+ where = "WHERE (key = ?)";
+ args.push(strKeyOrRange);
+ }
+ for (var indexName in objectStore._indexes)
+ {
+ var index = objectStore._indexes[indexName];
+ sql = ["DELETE FROM [" + util.indexTable(objectStore.name, index.name) + "]"];
+ if (args.length > 0)
+ {
+ sql.push("WHERE recordId IN (SELECT id FROM [" + objectStore.name + "]", where + ")");
+ }
+ sqlTx.executeSql(sql.join(" "), args, null, onerror);
+ }
+ sqlTx.executeSql("DELETE FROM [" + objectStore.name + "] " + where, args, onsuccess, onerror);
+ };
- function validateVersionChangeTx(tx)
+ IDBObjectStore.prototype._insertOrReplaceRecord = function (context, strKey)
{
- if (!tx || tx.mode !== util.IDBTransaction.VERSION_CHANGE)
+ var request = context.request;
+ if (!context.noOverwrite)
{
- throw util.error("InvalidStateError");
+ this._deleteRecord(context.sqlTx, strKey, null,
+ function (_, sqlError)
+ {
+ request.error = sqlError;
+ if (request.onerror) request.onerror(util.event("error", request));
+ context.nextRequestCallback();
+ });
}
- }
+ var me = this;
+ var strValue = w_JSON.stringify(context.value);
+ context.sqlTx.executeSql("INSERT INTO [" + me.name + "] (key, value) VALUES (?, ?)",
+ [strKey, strValue],
+ function (sqlTx, results)
+ {
+ context.objectStore = me;
+ context.sqlTx = sqlTx;
+ context.primaryKey = strKey;
+ context.recordId = results.insertId;
+ storeIndexes(context);
+ },
+ function (sqlTx, sqlError)
+ {
+ request.error = sqlError;
+ if (request.onerror) request.onerror(util.event("error", request));
+ context.nextRequestCallback();
+ });
+ };
+
+ // Utils
+ var w_JSON = window.JSON;
function isPositiveFloat(value)
{
View
4 IDBRequest.js
@@ -3,7 +3,7 @@ if (window.indexedDB.polyfill)
{
var IDBRequest = util.IDBRequest = window.IDBRequest = function(source)
{
- this.result = null;
+ this.result = undefined;
this.error = null;
this.source = source;
this.transaction = null;
@@ -16,7 +16,7 @@ if (window.indexedDB.polyfill)
var IDBOpenDBRequest = util.IDBOpenDBRequest = window.IDBOpenDBRequest = function(source)
{
- IDBRequest.call(this, arguments);
+ IDBRequest.apply(this, arguments);
this.onblocked = null;
this.onupgradeneeded = null;
};
View
20 IDBTransaction.js
@@ -40,10 +40,10 @@ if (window.indexedDB.polyfill)
{
me._active = false;
me._requests = [];
- for (var name in me.db._objectStores)
+ /*for (var name in me.db._objectStores)
{
me.db._objectStores[name].transaction = null;
- }
+ }*/
return;
}
operation = me._requests[operationIndex];
@@ -79,6 +79,22 @@ if (window.indexedDB.polyfill)
this._requests.push(sqlTxCallback);
};
+ IDBTransaction._assertNotReadOnly = function (tx)
+ {
+ if (tx.mode === util.IDBTransaction.READ_ONLY)
+ {
+ throw util.error("ReadOnlyError", "A mutation operation was attempted in a READ_ONLY transaction.");
+ }
+ };
+
+ IDBTransaction._assertVersionChange = function (tx)
+ {
+ if (!tx || tx.mode !== util.IDBTransaction.VERSION_CHANGE)
+ {
+ throw util.error("InvalidStateError");
+ }
+ };
+
IDBTransaction.READ_ONLY = "readonly";
IDBTransaction.READ_WRITE = "readwrite";
IDBTransaction.VERSION_CHANGE = "versionchange";
View
12 README
@@ -12,3 +12,15 @@ code needs to be wrapped by stop-start sign posts correctly and there must be on
very end, 'start' command may be executed too early leaving other async code with unit tests to be left out of a test
scope. This results test failures also affects to subsequent tests with outcomes like databases left unclosed or current
test's 'stop' stops the 'start' from previous unsuccessful test, thus leaving current closing 'start' without a match.
+
+
+B. Useful Resources.
+
+1) Test suits http://w3c-test.org/webapps/IndexedDB/.
+
+Among test suits from w3c-test.org/webapps/IndexedDB/tests/submissions/Microsoft/ the following are failing:
+idbdatabase_close*, idbdatabase_transaction*, idbfactory_cmp, idbfactory_open8,
+
+
+2) Mozilla IndexedDB implementation: http://hg.mozilla.org/mozilla-central/file/895e12563245/dom/indexedDB/ and
+http://people.mozilla.org/~jcranmer2/c-ccov-js/mozilla/dom/indexedDB/.
View
17 index.html
@@ -18,23 +18,8 @@
<script src="lib/jquery-1.7.2.js"></script>
<script type="text/javascript" src="lib/qunit.js"></script>
- <script type="text/javascript">
- if (!$.browser.mozilla)
- {
- window.indexedDB = { polyfill : true };
- }
- </script>
-
- <script type="text/javascript" src="indexedDB.polyfill.js"></script>
+ <script type="text/javascript" src="indexedDB.polyfill.debug.js"></script>
<script type="text/javascript" src="test/webkitIndexedDB.js"></script>
- <script type="text/javascript" src="IDBRequest.js"></script>
- <script type="text/javascript" src="IDBFactory.js"></script>
- <script type="text/javascript" src="IDBDatabase.js"></script>
- <script type="text/javascript" src="IDBTransaction.js"></script>
- <script type="text/javascript" src="IDBObjectStore.js"></script>
- <script type="text/javascript" src="IDBCursor.js"></script>
- <script type="text/javascript" src="IDBKeyRange.js"></script>
- <script type="text/javascript" src="IDBIndex.js"></script>
<script type="text/javascript" src="test/TestUtils.js"></script>
<script type="text/javascript" src="test/IDBFactoryTests.js"></script>
View
268 indexedDB.polyfill.js → indexedDB.init.js
@@ -1,124 +1,144 @@
-(function(window, undefined)
-{
- var indexedDB = window.indexedDB = window.indexedDB || window.mozIndexedDB ||
- window.webkitIndexedDB || window.msIndexedDB || { polyfill : true };
-
- window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
- window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
- window.IDBCursor = window.IDBCursor || window.webkitIDBCursor;
-
- if (!indexedDB.polyfill) return;
-
- console.warn('This browser most likely does not support IndexedDB technology. Initialing custom IndexedDB' +
- ' implementation using Web SQL Database technology.');
-
-
- // Configuration
- indexedDB.SCHEMA_TABLE = "__IndexedDBSchemaInfo__";
- indexedDB.DB_PREFIX = "__IndexedDB__";
- indexedDB.DB_DESCRIPTION = "IndexedDB ";
- indexedDB.DEFAULT_DB_SIZE = 5 * 1024 * 1024;
- indexedDB.CURSOR_CHUNK_SIZE = 10;
-
- // Data types
- indexedDB.DOMStringList = function () { };
- indexedDB.DOMStringList.prototype = [];
- indexedDB.DOMStringList.constructor = indexedDB.DOMStringList;
- indexedDB.DOMStringList.prototype.contains = function (str)
- {
- return this.indexOf(str) >= 0;
- };
-
-
- indexedDB.util = new (function ()
- {
- this.async = function (fn) { w_setTimeout(fn, 0); };
-
- this.error = function (name, message, innerError)
- {
- return {
- name : name,
- message : message,
- inner : innerError
- }
- };
-
- this.event = function (type, target)
- {
- return {
- type : type,
- target : target,
- currentTarget : target,
- preventDefault : function () { }
- };
- };
-
- this.validateKeyPath = function (keyPath)
- {
- if (keyPath === "") return "";
- if (keyPath == null) return null;
-
- var r = /^([^\d\W]\w*\.)+$/i;
- if (keyPath instanceof Array)
- {
- var i = keyPath.length;
- if (i == 0) throw this.error("SyntaxError");
-
- while (i--)
- {
- if (!r.test(keyPath[i] + ".")) throw this.error("SyntaxError");
- }
- return keyPath;
- }
- if (!r.test(keyPath + ".")) throw this.error("SyntaxError");
- return keyPath;
- };
-
- this.arrayRemove = function (array, item)
- {
- var i = array.indexOf(item);
- if (i > -1) array.splice(i, 1);
- };
-
- this.arrayAdd = function (array, item)
- {
- if (array.indexOf(item) == -1) array.push(item);
- };
-
- this.indexTable = function (objectStoreName, name)
- {
- return indexedDB.DB_PREFIX + "Index__" + objectStoreName + "__" + name;
- };
- });
-
- /*
- IDBVersionChangeEvent.prototype = new Event(null);
- IDBVersionChangeEvent.prototype.constructor = IDBVersionChangeEvent;
- function IDBVersionChangeEvent ()
- {
- this.oldVersoin = null;
- this.newVersion = null;
- }
- */
-
- var IDBDatabaseException = window.IDBDatabaseException =
- {
- ABORT_ERR : 8,
- CONSTRAINT_ERR : 4,
- DATA_ERR : 5,
- NON_TRANSIENT_ERR : 2,
- NOT_ALLOWED_ERR : 6,
- NOT_FOUND_ERR : 3,
- QUOTA_ERR : 11,
- READ_ONLY_ERR : 9,
- TIMEOUT_ERR : 10,
- TRANSACTION_INACTIVE_ERR : 7,
- UNKNOWN_ERR : 1,
- VERSION_ERR : 12
- };
-
- // Cached
- var w_Error = window.Error;
- var w_setTimeout = window.setTimeout;
-
-}(window));
+(function(window, undefined)
+{
+ var indexedDB = window.indexedDB = window.indexedDB || window.mozIndexedDB ||
+ window.webkitIndexedDB || window.msIndexedDB || { polyfill : true };
+
+ window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
+ window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
+ window.IDBCursor = window.IDBCursor || window.webkitIDBCursor;
+
+ if (!indexedDB.polyfill) return;
+
+ console.warn('This browser most likely does not support IndexedDB technology. Initializing custom IndexedDB' +
+ ' implementation using Web SQL Database technology.');
+
+
+ // Configuration
+ indexedDB.SCHEMA_TABLE = "__IndexedDBSchemaInfo__";
+ indexedDB.DB_PREFIX = "__IndexedDB__";
+ indexedDB.DB_DESCRIPTION = "IndexedDB ";
+ indexedDB.DEFAULT_DB_SIZE = 5 * 1024 * 1024;
+ indexedDB.CURSOR_CHUNK_SIZE = 10;
+
+ // Data types
+ indexedDB.DOMStringList = function () { };
+ indexedDB.DOMStringList.prototype = [];
+ indexedDB.DOMStringList.constructor = indexedDB.DOMStringList;
+ indexedDB.DOMStringList.prototype.contains = function (str)
+ {
+ return this.indexOf(str) >= 0;
+ };
+
+
+ indexedDB.util = new (function ()
+ {
+ this.async = function (fn) { w_setTimeout(fn, 0); };
+
+ this.error = function (name, message, innerError)
+ {
+ return {
+ name : name,
+ message : message,
+ inner : innerError
+ }
+ };
+
+ this.event = function (type, target)
+ {
+ return {
+ type : type,
+ target : target,
+ currentTarget : target,
+ preventDefault : function () { }
+ };
+ };
+
+ this.validateKeyPath = function (keyPath)
+ {
+ if (keyPath === "") return "";
+ if (keyPath == null) return null;
+
+ var r = /^([^\d\W]\w*\.)+$/i;
+ if (keyPath instanceof Array)
+ {
+ var i = keyPath.length;
+ if (i == 0) throw this.error("SyntaxError");
+
+ while (i--)
+ {
+ if (!r.test(keyPath[i] + ".")) throw this.error("SyntaxError");
+ }
+ return keyPath;
+ }
+ if (!r.test(keyPath + ".")) throw this.error("SyntaxError");
+ return keyPath;
+ };
+
+ this.arrayRemove = function (array, item)
+ {
+ var i = array.indexOf(item);
+ if (i > -1) array.splice(i, 1);
+ };
+
+ this.indexTable = function (objectStoreName, name)
+ {
+ return indexedDB.DB_PREFIX + "Index__" + objectStoreName + "__" + name;
+ };
+
+ this.extractKeyFromValue = function (keyPath, value)
+ {
+ var key;
+ if (keyPath instanceof Array)
+ {
+ key = [];
+ for (var i = 0; i < keyPath.length; i++)
+ {
+ key.push(extractKeyFromValue(value, keyPath[i]));
+ }
+ }
+ else
+ {
+ if (keyPath === "") return value;
+
+ key = value;
+ var paths = keyPath.split(".");
+ for (var i = 0; i < paths.length; i++)
+ {
+ if (key == null) return null;
+ key = key[paths[i]];
+ }
+ }
+ return key;
+ }
+ });
+
+ /*
+ IDBVersionChangeEvent.prototype = new Event(null);
+ IDBVersionChangeEvent.prototype.constructor = IDBVersionChangeEvent;
+ function IDBVersionChangeEvent ()
+ {
+ this.oldVersoin = null;
+ this.newVersion = null;
+ }
+ */
+
+ var IDBDatabaseException = window.IDBDatabaseException = indexedDB.util.IDBDatabaseException =
+ {
+ ABORT_ERR : 8,
+ CONSTRAINT_ERR : 4,
+ DATA_ERR : 5,
+ NON_TRANSIENT_ERR : 2,
+ NOT_ALLOWED_ERR : 6,
+ NOT_FOUND_ERR : 3,
+ QUOTA_ERR : 11,
+ READ_ONLY_ERR : 9,
+ TIMEOUT_ERR : 10,
+ TRANSACTION_INACTIVE_ERR : 7,
+ UNKNOWN_ERR : 1,
+ VERSION_ERR : 12
+ };
+
+ // Cached
+ var w_setTimeout = window.setTimeout;
+
+}(window));
View
36 indexedDB.polyfill.debug.js
@@ -0,0 +1,36 @@
+(function ()
+{
+ var files = [
+ "lib/jquery-1.7.2.js",
+ "indexedDB.init.js",
+ "IDBRequest.js",
+ "IDBFactory.js",
+ "IDBDatabase.js",
+ "IDBTransaction.js",
+ "IDBObjectStore.js",
+ "IDBCursor.js",
+ "IDBKeyRange.js",
+ "IDBIndex.js"
+ ];
+
+
+ function loadScript(i)
+ {
+ var s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.async = false;
+ s.src = "/git/" + files[i];
+ var x = document.getElementsByTagName('script')[0];
+ x.parentNode.insertBefore(s, x);
+ }
+
+ //loadScript(0);
+ if (!(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)))
+ {
+ window.indexedDB = { polyfill : true };
+ }
+ for (var i = 1; i < files.length; i++)
+ {
+ loadScript(i);
+ }
+}());
View
28 w3c-tests/Microsoft/idb_webworkers.htm
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IndexedDB inside of a WebWorker </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var t = async_test();
+
+ function RunTest() {
+ var worker = new Worker("idbworker.js");
+ worker.onmessage = t.step_func( function (event) {
+ assert_equals(event.data, true, 'self.indexedDB');
+ t.done();
+ });
+ worker.postMessage(1);
+ }
+
+ t.step( RunTest );
+
+ </script>
+</head>
+<body>
+<div id="log"></div>
+</body>
+</html>
View
73 w3c-tests/Microsoft/idbcursor_advance_index.htm
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title> IDBCursor.advance() - index - iterate cursor number of times specified by count </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" },
+ { pKey: "primaryKey_2", iKey: "indexKey_2" },
+ { pKey: "primaryKey_3", iKey: "indexKey_3" }];
+ var count = 0;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function(event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func(VerifyCursorIterates);
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorIterates() {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ if(cursor) {
+ switch(count) {
+ case 0:
+ count += 3;
+ cursor.advance(3);
+ break;
+ case 3:
+ var record = cursor.value;
+ assert_equals(record.pKey, records[count].pKey, "record.pKey");
+ assert_equals(record.iKey, records[count].iKey, "record.iKey");
+ t.done();
+ break;
+ default:
+ assert_unreached("unexpected count");
+ break;
+ }
+ }
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
69 w3c-tests/Microsoft/idbcursor_advance_objectstore.htm
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title> IDBCursor.advance() - object store - iterate cursor number of times specified by count </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var records = [ { pKey: "primaryKey_0" },
+ { pKey: "primaryKey_1" },
+ { pKey: "primaryKey_2" },
+ { pKey: "primaryKey_3" }];
+ var count = 0;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function(event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorIterates );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorIterates() {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ if(cursor) {
+ switch(count) {
+ case 0:
+ count += 3;
+ cursor.advance(3);
+ break;
+ case 3:
+ var record = cursor.value;
+ assert_equals(record.pKey, records[count].pKey, "record.pKey");
+ t.done();
+ break;
+ default:
+ assert_unreached("unexpected count");
+ break;
+ }
+ }
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
66 w3c-tests/Microsoft/idbcursor_continue_index.htm
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - index - iterate to the next record</title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var count = 0;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorIterates );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorIterates(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ if(cursor) {
+ var record = cursor.value;
+
+ assert_equals(record.pKey, records[count].pKey, "record.pKey");
+ assert_equals(record.iKey, records[count].iKey, "record.iKey");
+
+ count++;
+ cursor.continue();
+ } else {
+ assert_equals(count, records.length, "count");
+ t.done();
+ }
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
62 w3c-tests/Microsoft/idbcursor_continue_index2.htm
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - index - attempt to pass a key parameter is not a valid key </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(document);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
62 w3c-tests/Microsoft/idbcursor_continue_index3.htm
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - index - attempt to iterate to the previous record when the direction is set for the next record </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(records[0].iKey);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
63 w3c-tests/Microsoft/idbcursor_continue_index4.htm
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - index - attempt to iterate to the next record when the direction is set for the previous record </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var count = records.length;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor(IDBKeyRange.lowerBound(records[0].iKey), "prev");
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(records[1].iKey);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
63 w3c-tests/Microsoft/idbcursor_continue_objectstore.htm
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - object store - iterate to the next record</title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var records = [ { pKey: "primaryKey_0" },
+ { pKey: "primaryKey_1" }];
+ var count = 0;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorIterates );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorIterates(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ if(cursor) {
+ var record = cursor.value;
+
+ assert_equals(record.pKey, records[count].pKey, "record.pKey");
+
+ count++;
+ cursor.continue();
+ } else {
+ assert_equals(count, records.length, "count");
+ t.done();
+ }
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log">
+ </div>
+</body>
+</html>
View
60 w3c-tests/Microsoft/idbcursor_continue_objectstore2.htm
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - object store - attempt to pass a key parameter is not a valid key </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var records = [ { pKey: "primaryKey_0" },
+ { pKey: "primaryKey_1" }];
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(document);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log">
+ </div>
+</body>
+</html>
View
61 w3c-tests/Microsoft/idbcursor_continue_objectstore3.htm
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - object store - attempt to iterate to the previous record when the direction is set for the next record</title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var records = [ { pKey: "primaryKey_0" },
+ { pKey: "primaryKey_1" }];
+ var count = records.length;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(records[0].pKey);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log">
+ </div>
+</body>
+</html>
View
60 w3c-tests/Microsoft/idbcursor_continue_objectstore4.htm
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.continue() - object store - attempt to iterate to the next record when the direction is set for the previous record </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var records = [ { pKey: "primaryKey_0" },
+ { pKey: "primaryKey_1" }];
+ var count = records.length;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( VerifyCursorThrowsException );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function VerifyCursorThrowsException(event) {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor(IDBKeyRange.lowerBound(records[0].pKey), "prev");
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ try {
+ cursor.continue(records[1].pKey);
+ } catch(ex) {
+ assert_equals(ex.name, "DataError", "ex.name");
+ t.done();
+ return;
+ }
+ assert_expected_exception();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
72 w3c-tests/Microsoft/idbcursor_delete_index.htm
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.delete() - index - remove a record from the object store</title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var count = records.length;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( CursorDeleteRecord );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }
+
+ function CursorDeleteRecord(event) {
+ var txn = db.transaction(objectStoreName, "readwrite");
+ var objStore = txn.objectStore(objectStoreName);
+ var index = objStore.index(indexName);
+ var rqCursor = index.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+ cursor.delete();
+ });
+ txn.oncomplete = t.step_func( VerifyRecordWasDeleted );
+ }
+
+ function VerifyRecordWasDeleted() {
+ var txn = db.transaction(objectStoreName, "readonly");
+ var objStore = txn.objectStore(objectStoreName);
+ var rqCursor = objStore.openCursor();
+ rqCursor.onsuccess = t.step_func( function(event) {
+ var cursor = event.target.result;
+ assert_cursor_exists(cursor);
+
+ var record = cursor.value;
+ assert_equals(record.pKey, records[1].pKey, "record.pKey");
+ assert_equals(record.iKey, records[1].iKey, "record.iKey");
+ t.done();
+ });
+ }
+
+ add_completion_callback(function() { if(db) db.close(); });
+
+ setup(function() {
+ var rqDelete = window.indexedDB.deleteDatabase(databaseName);
+ rqDelete.onsuccess = t.step_func( RunTest );
+ });
+ </script>
+</head>
+<body>
+ <div id="log"></div>
+</body>
+</html>
View
63 w3c-tests/Microsoft/idbcursor_delete_index2.htm
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>IDBCursor.delete() - index - attempt to remove a record in a read-only transaction </title>
+ <script type="text/javascript" src="support.js"></script>
+ <script src="../testharness.js"></script>
+ <script src="../testharnessreport.js"></script>
+ <script src="/git/indexedDB.polyfill.debug.js"></script>
+ <script type="text/javascript">
+ var objectStoreName = "objectstore";
+ var indexName = "index";
+ var records = [ { pKey: "primaryKey_0", iKey: "indexKey_0" },
+ { pKey: "primaryKey_1", iKey: "indexKey_1" }];
+ var count = records.length;
+ var db = null;
+ var t = async_test();
+
+ function RunTest() {
+ var rqOpen = window.indexedDB.open(databaseName, databaseVersion);
+ rqOpen.onupgradeneeded = t.step_func( function (event) {
+ db = event.target.result;
+ db.onerror = t.step_func( assert_database_error );
+ var objStore = db.createObjectStore(objectStoreName, {keyPath:"pKey"});
+ objStore.createIndex(indexName, "iKey");
+ for(var i = 0; i < records.length; i++) {
+ objStore.add(records[i]);
+ }
+ });
+ rqOpen.onsuccess = t.step_func( CursorDeleteRecord );
+ rqOpen.onerror = t.step_func( assert_open_request_error );
+ }