public
Last active

Helper for creating an IDBKeyRange for all keys with a given prefix

  • Download Gist
idbkeyrange_forprefix.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
// Basic p(r)olyfill for proposed feature
 
// This defines no successor of empty arrays, so the range for prefix
// [] or [[],[]] has no upper bound.
// An alternate definition would preclude adding additional nesting,
// so the range for prefix [] would have upper bound [[]] and the
// range for prefix [[], []] would have upper bound [[], [[]]].
 
IDBKeyRange.forPrefix = function(prefix) {
// Ensure prefix is a valid key itself:
if (indexedDB.cmp(prefix, prefix) !== 0) throw new TypeError();
 
var MAX_DATE_VALUE = 8640000000000000;
var UPPER_BOUND = {
NUMBER: new Date(-MAX_DATE_VALUE),
DATE: "",
STRING: [],
ARRAY: undefined
};
 
var upperKey = successor(prefix);
if (upperKey === undefined)
return IDBKeyRange.lowerBound(prefix);
return IDBKeyRange.bound(prefix, upperKey, false, true);
 
function successor(key) {
 
if (typeof key === 'number') {
if (key === Infinity)
return UPPER_BOUND.NUMBER;
if (key === -Infinity)
return -Number.MAX_VALUE;
if (key === 0)
return Number.MIN_VALUE;
var epsilon = Math.abs(key);
while (key + epsilon / 2 !== key)
epsilon = epsilon / 2;
return key + epsilon;
}
 
if (key instanceof Date) {
if (key.valueOf() + 1 > MAX_DATE_VALUE)
return UPPER_BOUND.DATE;
return new Date(key.valueOf() + 1);
}
 
if (typeof key === 'string') {
var len = key.length;
while (len > 0) {
var head = key.substring(0, len - 1),
tail = key.charCodeAt(len - 1);
if (tail !== 0xFFFF)
return head + String.fromCharCode(tail + 1);
key = head;
--len;
}
return UPPER_BOUND.STRING;
}
 
if (Array.isArray(key)) {
key = key.slice(); // Operate on a copy.
len = key.length;
while (len > 0) {
tail = successor(key.pop());
if (tail !== undefined) {
key.push(tail);
return key;
}
--len;
}
return UPPER_BOUND.ARRAY;
}
 
throw new TypeError();
}
};

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.