Commit 2a773b8e authored by jsbell@chromium.org's avatar jsbell@chromium.org

IndexedDB: Treat count of 0 as unbounded for getAll() methods

After discussions w/ Moz and spec updates, modify the experimental
(behind a flag) IDBObjectStore/IDBIndex getAll()/getAllKeys() methods
to treat 0 the same as "not passed", and return as many results as
possible.

Also adds missing tests for IDBObjectStore.getAllKeys() and tweaks
the tests to avoid the deprecated assert_object_equals() function.

R=cmumford@chromium.org

Review URL: https://codereview.chromium.org/1303983002

git-svn-id: svn://svn.chromium.org/blink/trunk@200999 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 8ecb4688
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
<script src="../../resources/testharnessreport.js"></script> <script src="../../resources/testharnessreport.js"></script>
<script> <script>
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
var ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
function doSetup(dbName, dbVersion, onsuccess) { function doSetup(dbName, dbVersion, onsuccess) {
var delete_request = indexedDB.deleteDatabase(dbName); var delete_request = indexedDB.deleteDatabase(dbName);
delete_request.onerror = function() { delete_request.onerror = function() {
...@@ -17,7 +20,6 @@ function doSetup(dbName, dbVersion, onsuccess) { ...@@ -17,7 +20,6 @@ function doSetup(dbName, dbVersion, onsuccess) {
}; };
req.onupgradeneeded = function(evt) { req.onupgradeneeded = function(evt) {
var connection = evt.target.result; var connection = evt.target.result;
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
var store = connection.createObjectStore('generated', var store = connection.createObjectStore('generated',
{autoIncrement: true, keyPath: 'id'}); {autoIncrement: true, keyPath: 'id'});
...@@ -68,7 +70,7 @@ function createGetAllRequest(t, storeName, connection, range, maxCount) { ...@@ -68,7 +70,7 @@ function createGetAllRequest(t, storeName, connection, range, maxCount) {
var index = store.index('test_idx'); var index = store.index('test_idx');
// TODO(cmumford): Simplify once crbug.com/335871 is fixed. // TODO(cmumford): Simplify once crbug.com/335871 is fixed.
var req = maxCount !== undefined ? index.getAll(range, maxCount) : var req = maxCount !== undefined ? index.getAll(range, maxCount) :
range !== undefined ? index.getAll(range) : index.getAll(); range !== undefined ? index.getAll(range) : index.getAll();
req.onerror = t.unreached_func('getAll request should succeed'); req.onerror = t.unreached_func('getAll request should succeed');
return req; return req;
} }
...@@ -80,8 +82,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -80,8 +82,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 1); assert_array_equals(data.map(e => e.ch), ['c']);
assert_object_equals(data[0], {ch: 'c', upper: 'C'}); assert_array_equals(data.map(e => e.upper), ['C']);
t.done(); t.done();
}); });
}, 'Single item get'); }, 'Single item get');
...@@ -100,9 +102,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -100,9 +102,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 26); assert_array_equals(data.map(e => e.ch), alphabet);
assert_object_equals(data[0], {ch: 'a', upper: 'A'}); assert_array_equals(data.map(e => e.upper), ALPHABET);
assert_object_equals(data[25], {ch: 'z', upper: 'Z'});
t.done(); t.done();
}); });
}, 'Get all keys'); }, 'Get all keys');
...@@ -113,9 +114,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -113,9 +114,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 10); assert_array_equals(data.map(e => e.ch), 'abcdefghij'.split(''));
assert_object_equals(data[0], {ch: 'a', upper: 'A'}); assert_array_equals(data.map(e => e.upper), 'ABCDEFGHIJ'.split(''));
assert_object_equals(data[9], {ch: 'j', upper: 'J'});
t.done(); t.done();
}); });
}, 'maxCount=10'); }, 'maxCount=10');
...@@ -125,9 +125,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -125,9 +125,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
IDBKeyRange.bound('G', 'M')); IDBKeyRange.bound('G', 'M'));
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_equals(data.length, 7); assert_array_equals(data.map(e => e.ch), 'ghijklm'.split(''));
assert_object_equals(data[0], {ch: 'g', upper: 'G'}); assert_array_equals(data.map(e => e.upper), 'GHIJKLM'.split(''));
assert_object_equals(data[6], {ch: 'm', upper: 'M'});
t.done(); t.done();
}); });
}, 'Get bound range'); }, 'Get bound range');
...@@ -138,9 +137,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -138,9 +137,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 3); assert_array_equals(data.map(e => e.ch), 'ghi'.split(''));
assert_object_equals(data[0], {ch: 'g', upper: 'G'}); assert_array_equals(data.map(e => e.upper), 'GHI'.split(''));
assert_object_equals(data[2], {ch: 'i', upper: 'I'});
t.done(); t.done();
}); });
}, 'Get bound range with maxCount'); }, 'Get bound range with maxCount');
...@@ -151,11 +149,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -151,11 +149,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 4); assert_array_equals(data.map(e => e.ch), 'ghij'.split(''));
assert_object_equals(data[0], {ch: 'g', upper: 'G'}); assert_array_equals(data.map(e => e.upper), 'GHIJ'.split(''));
assert_object_equals(data[1], {ch: 'h', upper: 'H'});
assert_object_equals(data[2], {ch: 'i', upper: 'I'});
assert_object_equals(data[3], {ch: 'j', upper: 'J'});
t.done(); t.done();
}); });
}, 'Get upper excluded'); }, 'Get upper excluded');
...@@ -166,11 +161,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -166,11 +161,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 4); assert_array_equals(data.map(e => e.ch), 'hijk'.split(''));
assert_object_equals(data[0], {ch: 'h', upper: 'H'}); assert_array_equals(data.map(e => e.upper), 'HIJK'.split(''));
assert_object_equals(data[1], {ch: 'i', upper: 'I'});
assert_object_equals(data[2], {ch: 'j', upper: 'J'});
assert_object_equals(data[3], {ch: 'k', upper: 'K'});
t.done(); t.done();
}); });
}, 'Get lower excluded'); }, 'Get lower excluded');
...@@ -198,13 +190,15 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -198,13 +190,15 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
}, 'Non existent key'); }, 'Non existent key');
async_test(function(t) { async_test(function(t) {
var transaction = connection.transaction('out-of-line', 'readonly'); var req = createGetAllRequest(t, 'out-of-line', connection,
var store = transaction.objectStore('out-of-line'); undefined, 0);
var index = store.index('test_idx'); req.onsuccess = t.step_func(function(evt) {
assert_throws(new TypeError(), function () { var data = evt.target.result;
index.getAll(undefined, 0); assert_class_string(data, 'Array', 'result should be an array');
}, 'getAll() with maxCount=0 should throw TypeError'); assert_array_equals(data.map(e => e.ch), alphabet);
t.done(); assert_array_equals(data.map(e => e.upper), ALPHABET);
t.done();
});
}, 'maxCount=0'); }, 'maxCount=0');
async_test(function(t) { async_test(function(t) {
...@@ -213,9 +207,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -213,9 +207,8 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 13); assert_array_equals(data.map(e => e.ch), 'abcdefghijklm'.split(''));
assert_object_equals(data[0], {ch: 'a', half: 'first'}); assert_true(data.every(e => e.half === 'first'));
assert_object_equals(data[12], {ch: 'm', half: 'first'});
t.done(); t.done();
}); });
}, 'Retrieve multiEntry key'); }, 'Retrieve multiEntry key');
...@@ -226,12 +219,9 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) { ...@@ -226,12 +219,9 @@ doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_class_string(data, 'Array', 'result should be an array'); assert_class_string(data, 'Array', 'result should be an array');
assert_equals(data.length, 5); assert_array_equals(data.map(e => e.ch), ['a', 'e', 'i', 'o', 'u']);
assert_object_equals(data[0], {ch: 'a', attribs: ['vowel', 'first']}); assert_array_equals(data[0].attribs, ['vowel', 'first']);
assert_object_equals(data[1], {ch: 'e', attribs: ['vowel']}); assert_true(data.every(e => e.attribs[0] === 'vowel'));
assert_object_equals(data[2], {ch: 'i', attribs: ['vowel']});
assert_object_equals(data[3], {ch: 'o', attribs: ['vowel']});
assert_object_equals(data[4], {ch: 'u', attribs: ['vowel']});
t.done(); t.done();
}); });
}, 'Retrieve one key multiple values'); }, 'Retrieve one key multiple values');
......
...@@ -60,7 +60,8 @@ function createGetAllKeysRequest(t, storeName, connection, range, maxCount) { ...@@ -60,7 +60,8 @@ function createGetAllKeysRequest(t, storeName, connection, range, maxCount) {
var index = store.index('test_idx'); var index = store.index('test_idx');
// TODO(cmumford): Simplify once crbug.com/335871 is fixed. // TODO(cmumford): Simplify once crbug.com/335871 is fixed.
var req = maxCount !== undefined ? index.getAllKeys(range, maxCount) : var req = maxCount !== undefined ? index.getAllKeys(range, maxCount) :
range !== undefined ? index.getAllKeys(range) : index.getAllKeys(); range !== undefined ? index.getAllKeys(range) :
index.getAllKeys();
req.onerror = t.unreached_func('getAllKeys request should succeed'); req.onerror = t.unreached_func('getAllKeys request should succeed');
return req; return req;
} }
...@@ -182,13 +183,13 @@ doSetup(location.pathname + '-IDBIndex.getAllKeys', 1, function(evt) { ...@@ -182,13 +183,13 @@ doSetup(location.pathname + '-IDBIndex.getAllKeys', 1, function(evt) {
}, 'Non existent key'); }, 'Non existent key');
async_test(function(t) { async_test(function(t) {
var transaction = connection.transaction('out-of-line', 'readonly'); var req = createGetAllKeysRequest(t, 'out-of-line', connection,
var store = transaction.objectStore('out-of-line'); undefined, 0);
var index = store.index('test_idx'); req.onsuccess = t.step_func(function(evt) {
assert_throws(new TypeError(), function () { assert_array_equals(evt.target.result, alphabet,
index.getAllKeys(undefined, 0); 'getAllKeys() should return a..z');
}, 'getAllKeys() with maxCount=0 should throw TypeError'); t.done();
t.done(); });
}, 'maxCount=0'); }, 'maxCount=0');
async_test(function(t) { async_test(function(t) {
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<script src="../../resources/testharnessreport.js"></script> <script src="../../resources/testharnessreport.js"></script>
<script> <script>
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
function doSetup(dbName, dbVersion, onsuccess) { function doSetup(dbName, dbVersion, onsuccess) {
var delete_request = indexedDB.deleteDatabase(dbName); var delete_request = indexedDB.deleteDatabase(dbName);
delete_request.onerror = function() { delete_request.onerror = function() {
...@@ -17,7 +19,6 @@ function doSetup(dbName, dbVersion, onsuccess) { ...@@ -17,7 +19,6 @@ function doSetup(dbName, dbVersion, onsuccess) {
}; };
req.onupgradeneeded = function(evt) { req.onupgradeneeded = function(evt) {
var connection = evt.target.result; var connection = evt.target.result;
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
var store = connection.createObjectStore('generated', var store = connection.createObjectStore('generated',
{autoIncrement: true, keyPath: 'id'}); {autoIncrement: true, keyPath: 'id'});
...@@ -27,7 +28,7 @@ function doSetup(dbName, dbVersion, onsuccess) { ...@@ -27,7 +28,7 @@ function doSetup(dbName, dbVersion, onsuccess) {
store = connection.createObjectStore('out-of-line', null); store = connection.createObjectStore('out-of-line', null);
alphabet.forEach(function(letter) { alphabet.forEach(function(letter) {
store.put(letter, letter); store.put('value-' + letter, letter);
}); });
store = connection.createObjectStore('empty', null); store = connection.createObjectStore('empty', null);
...@@ -40,7 +41,7 @@ function createGetAllRequest(t, storeName, connection, range, maxCount) { ...@@ -40,7 +41,7 @@ function createGetAllRequest(t, storeName, connection, range, maxCount) {
var store = transaction.objectStore(storeName); var store = transaction.objectStore(storeName);
// TODO(cmumford): Simplify once crbug.com/335871 is closed. // TODO(cmumford): Simplify once crbug.com/335871 is closed.
var req = maxCount !== undefined ? store.getAll(range, maxCount) : var req = maxCount !== undefined ? store.getAll(range, maxCount) :
range !== undefined ? store.getAll(range) : store.getAll(); range !== undefined ? store.getAll(range) : store.getAll();
req.onerror = t.unreached_func('getAll request should succeed'); req.onerror = t.unreached_func('getAll request should succeed');
return req; return req;
} }
...@@ -50,7 +51,7 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -50,7 +51,7 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
async_test(function(t) { async_test(function(t) {
var req = createGetAllRequest(t, 'out-of-line', connection, 'c'); var req = createGetAllRequest(t, 'out-of-line', connection, 'c');
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['c']); assert_array_equals(evt.target.result, ['value-c']);
t.done(); t.done();
}); });
}, 'Single item get'); }, 'Single item get');
...@@ -61,7 +62,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -61,7 +62,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_true(Array.isArray(data)); assert_true(Array.isArray(data));
assert_equals(data.length, 1); assert_equals(data.length, 1);
assert_object_equals(data[0], {ch: 'c', id: 3}); assert_equals(data[0].id, 3);
assert_equals(data[0].ch, 'c');
t.done(); t.done();
}); });
}, 'Single item get (generated key)'); }, 'Single item get (generated key)');
...@@ -79,7 +81,7 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -79,7 +81,7 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
var req = createGetAllRequest(t, 'out-of-line', connection); var req = createGetAllRequest(t, 'out-of-line', connection);
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, assert_array_equals(evt.target.result,
'abcdefghijklmnopqrstuvwxyz'.split('')); alphabet.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Get all values'); }, 'Get all values');
...@@ -89,7 +91,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -89,7 +91,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
10); 10);
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, assert_array_equals(evt.target.result,
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']); ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Test maxCount'); }, 'Test maxCount');
...@@ -99,7 +102,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -99,7 +102,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
IDBKeyRange.bound('g', 'm')); IDBKeyRange.bound('g', 'm'));
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, assert_array_equals(evt.target.result,
['g', 'h', 'i', 'j', 'k', 'l', 'm']); ['g', 'h', 'i', 'j', 'k', 'l', 'm']
.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Get bound range'); }, 'Get bound range');
...@@ -108,7 +112,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -108,7 +112,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
var req = createGetAllRequest(t, 'out-of-line', connection, var req = createGetAllRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'm'), 3); IDBKeyRange.bound('g', 'm'), 3);
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['g', 'h', 'i']); assert_array_equals(evt.target.result, ['g', 'h', 'i']
.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Get bound range with maxCount'); }, 'Get bound range with maxCount');
...@@ -117,7 +122,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -117,7 +122,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
var req = createGetAllRequest(t, 'out-of-line', connection, var req = createGetAllRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'k', false, true)); IDBKeyRange.bound('g', 'k', false, true));
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['g', 'h', 'i', 'j']); assert_array_equals(evt.target.result, ['g', 'h', 'i', 'j']
.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Get upper excluded'); }, 'Get upper excluded');
...@@ -126,7 +132,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -126,7 +132,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
var req = createGetAllRequest(t, 'out-of-line', connection, var req = createGetAllRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'k', true, false)); IDBKeyRange.bound('g', 'k', true, false));
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['h', 'i', 'j', 'k']); assert_array_equals(evt.target.result, ['h', 'i', 'j', 'k']
.map(c => 'value-' + c));
t.done(); t.done();
}); });
}, 'Get lower excluded'); }, 'Get lower excluded');
...@@ -137,10 +144,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -137,10 +144,8 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
req.onsuccess = t.step_func(function(evt) { req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result; var data = evt.target.result;
assert_true(Array.isArray(data)); assert_true(Array.isArray(data));
assert_equals(data.length, 3); assert_array_equals(data.map(e => e.ch), ['d', 'e', 'f']);
assert_object_equals(data[0], {ch: 'd', id: 4}); assert_array_equals(data.map(e => e.id), [4, 5, 6]);
assert_object_equals(data[1], {ch: 'e', id: 5});
assert_object_equals(data[2], {ch: 'f', id: 6});
t.done(); t.done();
}); });
}, 'Get bound range (generated) with maxCount'); }, 'Get bound range (generated) with maxCount');
...@@ -157,12 +162,12 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) { ...@@ -157,12 +162,12 @@ doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
}, 'Non existent key'); }, 'Non existent key');
async_test(function(t) { async_test(function(t) {
var transaction = connection.transaction('out-of-line', 'readonly'); var req = createGetAllRequest(t, 'out-of-line', connection, undefined, 0);
var store = transaction.objectStore('out-of-line'); req.onsuccess = t.step_func(function(evt) {
assert_throws(new TypeError(), function () { assert_array_equals(evt.target.result,
store.getAll(undefined, 0); alphabet.map(c => 'value-' + c));
}, 'getAll() with maxCount=0 should throw TypeError'); t.done();
t.done(); });
}, 'zero maxCount'); }, 'zero maxCount');
}); });
......
<!DOCTYPE html>
<title>IndexedDB: Test IDBObjectStore.getAllKeys.</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
function doSetup(dbName, dbVersion, onsuccess) {
var delete_request = indexedDB.deleteDatabase(dbName);
delete_request.onerror = function() {
assert_unreached('deleteDatabase should not fail');
};
delete_request.onsuccess = function(e) {
var req = indexedDB.open(dbName, dbVersion);
req.onsuccess = onsuccess;
req.onerror = function() {
assert_unreached('open should not fail');
};
req.onupgradeneeded = function(evt) {
var connection = evt.target.result;
var store = connection.createObjectStore('generated',
{autoIncrement: true, keyPath: 'id'});
alphabet.forEach(function(letter) {
store.put({ch: letter});
});
store = connection.createObjectStore('out-of-line', null);
alphabet.forEach(function(letter) {
store.put('value-' + letter, letter);
});
store = connection.createObjectStore('empty', null);
};
};
}
function createGetAllKeysRequest(t, storeName, connection, range, maxCount) {
var transaction = connection.transaction(storeName, 'readonly');
var store = transaction.objectStore(storeName);
// TODO(cmumford): Simplify once crbug.com/335871 is closed.
var req = maxCount !== undefined ? store.getAllKeys(range, maxCount) :
range !== undefined ? store.getAllKeys(range) :
store.getAllKeys();
req.onerror = t.unreached_func('getAllKeys request should succeed');
return req;
}
doSetup(location.pathname + '-IDBObjectStore.getAllKeys', 1, function(evt) {
var connection = evt.target.result;
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection, 'c');
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['c']);
t.done();
});
}, 'Single item get');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'generated', connection, 3);
req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result;
assert_true(Array.isArray(data));
assert_array_equals(data, [3]);
t.done();
});
}, 'Single item get (generated key)');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'empty', connection);
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, [],
'getAllKeys() on empty object store should return an empty ' +
'array');
t.done();
});
}, 'getAllKeys on empty object store');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection);
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, alphabet);
t.done();
});
}, 'Get all values');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection, undefined,
10);
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result,
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']);
t.done();
});
}, 'Test maxCount');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'm'));
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result,
['g', 'h', 'i', 'j', 'k', 'l', 'm']);
t.done();
});
}, 'Get bound range');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'm'), 3);
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['g', 'h', 'i']);
t.done();
});
}, 'Get bound range with maxCount');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'k', false, true));
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['g', 'h', 'i', 'j']);
t.done();
});
}, 'Get upper excluded');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection,
IDBKeyRange.bound('g', 'k', true, false));
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, ['h', 'i', 'j', 'k']);
t.done();
});
}, 'Get lower excluded');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'generated', connection,
IDBKeyRange.bound(4, 15), 3);
req.onsuccess = t.step_func(function(evt) {
var data = evt.target.result;
assert_true(Array.isArray(data));
assert_array_equals(data, [4, 5, 6]);
t.done();
});
}, 'Get bound range (generated) with maxCount');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection,
"Doesn't exist");
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, [],
'getAllKeys() using a nonexistent key should return an ' +
'empty array');
t.done();
});
req.onerror = t.unreached_func('getAllKeys request should succeed');
}, 'Non existent key');
async_test(function(t) {
var req = createGetAllKeysRequest(t, 'out-of-line', connection, undefined,
0);
req.onsuccess = t.step_func(function(evt) {
assert_array_equals(evt.target.result, alphabet);
t.done();
});
}, 'zero maxCount');
});
</script>
...@@ -67,7 +67,6 @@ const char IDBDatabase::transactionInactiveErrorMessage[] = "The transaction is ...@@ -67,7 +67,6 @@ const char IDBDatabase::transactionInactiveErrorMessage[] = "The transaction is
const char IDBDatabase::transactionFinishedErrorMessage[] = "The transaction has finished."; const char IDBDatabase::transactionFinishedErrorMessage[] = "The transaction has finished.";
const char IDBDatabase::transactionReadOnlyErrorMessage[] = "The transaction is read-only."; const char IDBDatabase::transactionReadOnlyErrorMessage[] = "The transaction is read-only.";
const char IDBDatabase::databaseClosedErrorMessage[] = "The database connection is closed."; const char IDBDatabase::databaseClosedErrorMessage[] = "The database connection is closed.";
const char IDBDatabase::notValidMaxCountErrorMessage[] = "The maxCount provided must not be 0.";
IDBDatabase* IDBDatabase::create(ExecutionContext* context, PassOwnPtr<WebIDBDatabase> database, IDBDatabaseCallbacks* callbacks) IDBDatabase* IDBDatabase::create(ExecutionContext* context, PassOwnPtr<WebIDBDatabase> database, IDBDatabaseCallbacks* callbacks)
{ {
......
...@@ -128,7 +128,6 @@ public: ...@@ -128,7 +128,6 @@ public:
static const char transactionInactiveErrorMessage[]; static const char transactionInactiveErrorMessage[];
static const char transactionReadOnlyErrorMessage[]; static const char transactionReadOnlyErrorMessage[];
static const char databaseClosedErrorMessage[]; static const char databaseClosedErrorMessage[];
static const char notValidMaxCountErrorMessage[];
protected: protected:
// EventTarget // EventTarget
......
...@@ -235,10 +235,9 @@ IDBRequest* IDBIndex::getInternal(ScriptState* scriptState, const ScriptValue& k ...@@ -235,10 +235,9 @@ IDBRequest* IDBIndex::getInternal(ScriptState* scriptState, const ScriptValue& k
IDBRequest* IDBIndex::getAllInternal(ScriptState* scriptState, const ScriptValue& range, unsigned long maxCount, ExceptionState& exceptionState, bool keyOnly) IDBRequest* IDBIndex::getAllInternal(ScriptState* scriptState, const ScriptValue& range, unsigned long maxCount, ExceptionState& exceptionState, bool keyOnly)
{ {
if (!maxCount) { if (!maxCount)
exceptionState.throwTypeError(IDBDatabase::notValidMaxCountErrorMessage); maxCount = std::numeric_limits<uint32_t>::max();
return nullptr;
}
if (isDeleted()) { if (isDeleted()) {
exceptionState.throwDOMException(InvalidStateError, IDBDatabase::indexDeletedErrorMessage); exceptionState.throwDOMException(InvalidStateError, IDBDatabase::indexDeletedErrorMessage);
return nullptr; return nullptr;
......
...@@ -126,10 +126,9 @@ IDBRequest* IDBObjectStore::getAll(ScriptState* scriptState, const ScriptValue& ...@@ -126,10 +126,9 @@ IDBRequest* IDBObjectStore::getAll(ScriptState* scriptState, const ScriptValue&
IDBRequest* IDBObjectStore::getAll(ScriptState* scriptState, const ScriptValue& keyRange, unsigned long maxCount, ExceptionState& exceptionState) IDBRequest* IDBObjectStore::getAll(ScriptState* scriptState, const ScriptValue& keyRange, unsigned long maxCount, ExceptionState& exceptionState)
{ {
IDB_TRACE("IDBObjectStore::getAll"); IDB_TRACE("IDBObjectStore::getAll");
if (!maxCount) { if (!maxCount)
exceptionState.throwTypeError(IDBDatabase::notValidMaxCountErrorMessage); maxCount = std::numeric_limits<uint32_t>::max();
return nullptr;
}
if (isDeleted()) { if (isDeleted()) {
exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage);
return nullptr; return nullptr;
...@@ -163,10 +162,9 @@ IDBRequest* IDBObjectStore::getAllKeys(ScriptState* scriptState, const ScriptVal ...@@ -163,10 +162,9 @@ IDBRequest* IDBObjectStore::getAllKeys(ScriptState* scriptState, const ScriptVal
IDBRequest* IDBObjectStore::getAllKeys(ScriptState* scriptState, const ScriptValue& keyRange, unsigned long maxCount, ExceptionState& exceptionState) IDBRequest* IDBObjectStore::getAllKeys(ScriptState* scriptState, const ScriptValue& keyRange, unsigned long maxCount, ExceptionState& exceptionState)
{ {
IDB_TRACE("IDBObjectStore::getAll"); IDB_TRACE("IDBObjectStore::getAll");
if (!maxCount) { if (!maxCount)
exceptionState.throwTypeError(IDBDatabase::notValidMaxCountErrorMessage); maxCount = std::numeric_limits<uint32_t>::max();
return 0;
}
if (isDeleted()) { if (isDeleted()) {
exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment