idb: implement missing methods
This commit is contained in:
parent
29d23b192d
commit
9c85f6277b
@ -860,6 +860,45 @@ export class MemoryBackend implements Backend {
|
||||
});
|
||||
}
|
||||
|
||||
async clearObjectStore(
|
||||
btx: DatabaseTransaction,
|
||||
objectStoreName: string,
|
||||
): Promise<void> {
|
||||
const myConn = this.requireConnectionFromTransaction(btx);
|
||||
const db = this.databases[myConn.dbName];
|
||||
if (!db) {
|
||||
throw Error("db not found");
|
||||
}
|
||||
if (db.txLevel < TransactionLevel.Write) {
|
||||
throw Error("only allowed in write transaction");
|
||||
}
|
||||
if (
|
||||
db.txRestrictObjectStores &&
|
||||
!db.txRestrictObjectStores.includes(objectStoreName)
|
||||
) {
|
||||
throw Error(
|
||||
`Not allowed to access store '${objectStoreName}', transaction is over ${JSON.stringify(
|
||||
db.txRestrictObjectStores,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const schema = myConn.modifiedSchema;
|
||||
const objectStoreMapEntry = myConn.objectStoreMap[objectStoreName];
|
||||
|
||||
objectStoreMapEntry.store.modifiedData = new BTree([], compareKeys);
|
||||
|
||||
for (const indexName of Object.keys(
|
||||
schema.objectStores[objectStoreName].indexes,
|
||||
)) {
|
||||
const index = myConn.objectStoreMap[objectStoreName].indexMap[indexName];
|
||||
if (!index) {
|
||||
throw Error("index referenced by object store does not exist");
|
||||
}
|
||||
index.modifiedData = new BTree([], compareKeys);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteRecord(
|
||||
btx: DatabaseTransaction,
|
||||
objectStoreName: string,
|
||||
|
@ -216,4 +216,9 @@ export interface Backend {
|
||||
btx: DatabaseTransaction,
|
||||
storeReq: RecordStoreRequest,
|
||||
): Promise<RecordStoreResponse>;
|
||||
|
||||
clearObjectStore(
|
||||
btx: DatabaseTransaction,
|
||||
objectStoreName: string,
|
||||
): Promise<void>
|
||||
}
|
||||
|
@ -1234,11 +1234,48 @@ export class BridgeIDBIndex implements IDBIndex {
|
||||
query?: BridgeIDBKeyRange | IDBValidKey,
|
||||
count?: number,
|
||||
): IDBRequest<any[]> {
|
||||
throw Error("not implemented");
|
||||
this._confirmIndexExists();
|
||||
this._confirmActiveTransaction();
|
||||
if (this._deleted) {
|
||||
throw new InvalidStateError();
|
||||
}
|
||||
|
||||
if (!(query instanceof BridgeIDBKeyRange)) {
|
||||
query = BridgeIDBKeyRange._valueToKeyRange(query);
|
||||
}
|
||||
|
||||
if (count === undefined) {
|
||||
count = -1;
|
||||
}
|
||||
|
||||
const getReq: RecordGetRequest = {
|
||||
direction: "next",
|
||||
indexName: this._name,
|
||||
limit: count,
|
||||
range: query,
|
||||
objectStoreName: this._objectStore._name,
|
||||
resultLevel: ResultLevel.Full,
|
||||
};
|
||||
|
||||
const operation = async () => {
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
const result = await this._backend.getRecords(btx, getReq);
|
||||
const values = result.values;
|
||||
if (!values) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
return values.map((x) => structuredRevive(x));
|
||||
};
|
||||
|
||||
return this._objectStore._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBIndex-getKey-IDBRequest-any-key
|
||||
public getKey(key: BridgeIDBKeyRange | IDBValidKey) {
|
||||
this._confirmIndexExists();
|
||||
this._confirmActiveTransaction();
|
||||
|
||||
if (!(key instanceof BridgeIDBKeyRange)) {
|
||||
@ -1278,11 +1315,45 @@ export class BridgeIDBIndex implements IDBIndex {
|
||||
query?: BridgeIDBKeyRange | IDBValidKey,
|
||||
count?: number,
|
||||
): IDBRequest<IDBValidKey[]> {
|
||||
throw Error("not implemented");
|
||||
this._confirmIndexExists();
|
||||
this._confirmActiveTransaction();
|
||||
|
||||
if (!(query instanceof BridgeIDBKeyRange)) {
|
||||
query = BridgeIDBKeyRange._valueToKeyRange(query);
|
||||
}
|
||||
|
||||
if (count === undefined) {
|
||||
count = -1;
|
||||
}
|
||||
|
||||
const getReq: RecordGetRequest = {
|
||||
direction: "next",
|
||||
indexName: this._name,
|
||||
limit: count,
|
||||
range: query,
|
||||
objectStoreName: this._objectStore._name,
|
||||
resultLevel: ResultLevel.OnlyKeys,
|
||||
};
|
||||
|
||||
const operation = async () => {
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
const result = await this._backend.getRecords(btx, getReq);
|
||||
const primaryKeys = result.primaryKeys;
|
||||
if (!primaryKeys) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
return primaryKeys;
|
||||
};
|
||||
|
||||
return this._objectStore._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBIndex-count-IDBRequest-any-key
|
||||
public count(key: BridgeIDBKeyRange | IDBValidKey | null | undefined) {
|
||||
this._confirmIndexExists();
|
||||
this._confirmActiveTransaction();
|
||||
|
||||
if (key === null) {
|
||||
@ -1718,14 +1789,147 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
|
||||
query?: BridgeIDBKeyRange | IDBValidKey,
|
||||
count?: number,
|
||||
): IDBRequest<any[]> {
|
||||
throw Error("not implemented");
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log(`getting from object store ${this._name} key ${query}`);
|
||||
}
|
||||
|
||||
if (arguments.length === 0) {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
if (!this._transaction._active) {
|
||||
throw new TransactionInactiveError();
|
||||
}
|
||||
|
||||
if (this._deleted) {
|
||||
throw new InvalidStateError(
|
||||
"tried to call 'delete' on a deleted object store",
|
||||
);
|
||||
}
|
||||
|
||||
if (count === undefined) {
|
||||
count = -1;
|
||||
}
|
||||
|
||||
let keyRange: BridgeIDBKeyRange;
|
||||
|
||||
if (query instanceof BridgeIDBKeyRange) {
|
||||
keyRange = query;
|
||||
} else {
|
||||
try {
|
||||
keyRange = BridgeIDBKeyRange.only(valueToKey(query));
|
||||
} catch (e) {
|
||||
throw new DataError(
|
||||
`invalid key (type ${typeof query}) for object store '${this._name}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const recordRequest: RecordGetRequest = {
|
||||
objectStoreName: this._name,
|
||||
indexName: undefined,
|
||||
lastIndexPosition: undefined,
|
||||
lastObjectStorePosition: undefined,
|
||||
direction: "next",
|
||||
limit: count,
|
||||
resultLevel: ResultLevel.Full,
|
||||
range: keyRange,
|
||||
};
|
||||
|
||||
const operation = async () => {
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("running getAll operation:", recordRequest);
|
||||
}
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
const result = await this._backend.getRecords(btx, recordRequest);
|
||||
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("get operation result count:", result.count);
|
||||
}
|
||||
const values = result.values;
|
||||
if (!values) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
return values.map((x) => structuredRevive(x));
|
||||
};
|
||||
|
||||
return this._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
// http://w3c.github.io/IndexedDB/#dom-idbobjectstore-getkey
|
||||
public getKey(
|
||||
key?: BridgeIDBKeyRange | IDBValidKey,
|
||||
query?: BridgeIDBKeyRange | IDBValidKey,
|
||||
): IDBRequest<IDBValidKey | undefined> {
|
||||
throw Error("not implemented");
|
||||
if (arguments.length === 0) {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
if (!this._transaction._active) {
|
||||
throw new TransactionInactiveError();
|
||||
}
|
||||
|
||||
if (this._deleted) {
|
||||
throw new InvalidStateError(
|
||||
"tried to call 'delete' on a deleted object store",
|
||||
);
|
||||
}
|
||||
|
||||
let keyRange: BridgeIDBKeyRange;
|
||||
|
||||
if (query instanceof BridgeIDBKeyRange) {
|
||||
keyRange = query;
|
||||
} else {
|
||||
try {
|
||||
keyRange = BridgeIDBKeyRange.only(valueToKey(query));
|
||||
} catch (e) {
|
||||
throw new DataError(
|
||||
`invalid key (type ${typeof query}) for object store '${this._name}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const recordRequest: RecordGetRequest = {
|
||||
objectStoreName: this._name,
|
||||
indexName: undefined,
|
||||
lastIndexPosition: undefined,
|
||||
lastObjectStorePosition: undefined,
|
||||
direction: "next",
|
||||
limit: 1,
|
||||
resultLevel: ResultLevel.OnlyKeys,
|
||||
range: keyRange,
|
||||
};
|
||||
|
||||
const operation = async () => {
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("running get operation:", recordRequest);
|
||||
}
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
const result = await this._backend.getRecords(btx, recordRequest);
|
||||
|
||||
if (BridgeIDBFactory.enableTracing) {
|
||||
console.log("get operation result count:", result.count);
|
||||
}
|
||||
|
||||
if (result.count === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const primaryKeys = result.primaryKeys;
|
||||
if (!primaryKeys) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
if (primaryKeys.length !== 1) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
return structuredRevive(primaryKeys[0]);
|
||||
};
|
||||
|
||||
return this._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
// http://w3c.github.io/IndexedDB/#dom-idbobjectstore-getallkeys
|
||||
@ -1733,11 +1937,86 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
|
||||
query?: BridgeIDBKeyRange | IDBValidKey,
|
||||
count?: number,
|
||||
): IDBRequest<any[]> {
|
||||
throw Error("not implemented");
|
||||
if (arguments.length === 0) {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
if (!this._transaction._active) {
|
||||
throw new TransactionInactiveError();
|
||||
}
|
||||
|
||||
if (this._deleted) {
|
||||
throw new InvalidStateError(
|
||||
"tried to call 'delete' on a deleted object store",
|
||||
);
|
||||
}
|
||||
|
||||
if (count === undefined) {
|
||||
count = -1;
|
||||
}
|
||||
|
||||
let keyRange: BridgeIDBKeyRange;
|
||||
|
||||
if (query instanceof BridgeIDBKeyRange) {
|
||||
keyRange = query;
|
||||
} else {
|
||||
try {
|
||||
keyRange = BridgeIDBKeyRange.only(valueToKey(query));
|
||||
} catch (e) {
|
||||
throw new DataError(
|
||||
`invalid key (type ${typeof query}) for object store '${this._name}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const recordRequest: RecordGetRequest = {
|
||||
objectStoreName: this._name,
|
||||
indexName: undefined,
|
||||
lastIndexPosition: undefined,
|
||||
lastObjectStorePosition: undefined,
|
||||
direction: "next",
|
||||
limit: count,
|
||||
resultLevel: ResultLevel.OnlyKeys,
|
||||
range: keyRange,
|
||||
};
|
||||
|
||||
const operation = async () => {
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
const result = await this._backend.getRecords(btx, recordRequest);
|
||||
|
||||
const primaryKeys = result.primaryKeys;
|
||||
if (!primaryKeys) {
|
||||
throw Error("invariant violated");
|
||||
}
|
||||
return primaryKeys.map((x) => structuredRevive(x));
|
||||
};
|
||||
|
||||
return this._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
public clear(): IDBRequest<undefined> {
|
||||
throw Error("not implemented");
|
||||
public clear(): IDBRequest {
|
||||
if (!this._transaction._active) {
|
||||
throw new TransactionInactiveError();
|
||||
}
|
||||
|
||||
if (this._deleted) {
|
||||
throw new InvalidStateError(
|
||||
"tried to call 'delete' on a deleted object store",
|
||||
);
|
||||
}
|
||||
|
||||
const operation = async () => {
|
||||
const { btx } = this._confirmStartedBackendTransaction();
|
||||
await this._backend.clearObjectStore(btx, this._name);
|
||||
};
|
||||
|
||||
return this._transaction._execRequestAsync({
|
||||
operation,
|
||||
source: this,
|
||||
});
|
||||
}
|
||||
|
||||
public openCursor(
|
||||
@ -2228,12 +2507,12 @@ export class BridgeIDBTransaction
|
||||
if (this._db._upgradeTransaction) {
|
||||
for (const os of this._usedObjectStores) {
|
||||
if (os._justCreated) {
|
||||
os._deleted = true
|
||||
os._deleted = true;
|
||||
}
|
||||
}
|
||||
for (const ind of this._usedIndexes) {
|
||||
if (ind._justCreated) {
|
||||
ind._deleted = true
|
||||
ind._deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ importers:
|
||||
typeson: 5.18.2
|
||||
typeson-registry: 1.0.0-alpha.38
|
||||
devDependencies:
|
||||
'@rollup/plugin-commonjs': 17.1.0_rollup@2.37.1
|
||||
'@rollup/plugin-json': 4.1.0_rollup@2.37.1
|
||||
'@rollup/plugin-node-resolve': 11.2.0_rollup@2.37.1
|
||||
'@types/node': 14.14.22
|
||||
ava: 3.15.0
|
||||
esm: 3.2.25
|
||||
@ -15,6 +18,9 @@ importers:
|
||||
rollup: 2.37.1
|
||||
typescript: 4.1.3
|
||||
specifiers:
|
||||
'@rollup/plugin-commonjs': ^17.1.0
|
||||
'@rollup/plugin-json': ^4.1.0
|
||||
'@rollup/plugin-node-resolve': ^11.2.0
|
||||
'@types/node': ^14.14.22
|
||||
ava: ^3.15.0
|
||||
esm: ^3.2.25
|
||||
@ -520,6 +526,23 @@ packages:
|
||||
rollup: ^2.30.0
|
||||
resolution:
|
||||
integrity: sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==
|
||||
/@rollup/plugin-commonjs/17.1.0_rollup@2.37.1:
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.37.1
|
||||
commondir: 1.0.1
|
||||
estree-walker: 2.0.2
|
||||
glob: 7.1.6
|
||||
is-reference: 1.2.1
|
||||
magic-string: 0.25.7
|
||||
resolve: 1.20.0
|
||||
rollup: 2.37.1
|
||||
dev: true
|
||||
engines:
|
||||
node: '>= 8.0.0'
|
||||
peerDependencies:
|
||||
rollup: ^2.30.0
|
||||
resolution:
|
||||
integrity: sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==
|
||||
/@rollup/plugin-json/4.1.0_rollup@2.37.1:
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.37.1
|
||||
@ -545,6 +568,22 @@ packages:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
resolution:
|
||||
integrity: sha512-ouBBppRdWJKCllDXGzJ7ZIkYbaq+5TmyP0smt1vdJCFfoZhLi31vhpmjLhyo8lreHf4RoeSNllaWrvSqHpHRog==
|
||||
/@rollup/plugin-node-resolve/11.2.0_rollup@2.37.1:
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.37.1
|
||||
'@types/resolve': 1.17.1
|
||||
builtin-modules: 3.2.0
|
||||
deepmerge: 4.2.2
|
||||
is-module: 1.0.0
|
||||
resolve: 1.20.0
|
||||
rollup: 2.37.1
|
||||
dev: true
|
||||
engines:
|
||||
node: '>= 10.0.0'
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
resolution:
|
||||
integrity: sha512-qHjNIKYt5pCcn+5RUBQxK8krhRvf1HnyVgUCcFFcweDS7fhkOLZeYh0mhHK6Ery8/bb9tvN/ubPzmfF0qjDCTA==
|
||||
/@rollup/plugin-replace/2.3.4_rollup@2.37.1:
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.37.1
|
||||
@ -684,6 +723,10 @@ packages:
|
||||
/@types/node/14.14.22:
|
||||
resolution:
|
||||
integrity: sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
|
||||
/@types/node/14.14.31:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
|
||||
/@types/normalize-package-data/2.4.0:
|
||||
dev: true
|
||||
resolution:
|
||||
@ -707,7 +750,7 @@ packages:
|
||||
integrity: sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==
|
||||
/@types/resolve/1.17.1:
|
||||
dependencies:
|
||||
'@types/node': 14.14.22
|
||||
'@types/node': 14.14.31
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==
|
||||
@ -3296,6 +3339,7 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
/lodash.sortby/4.7.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||
/lodash/4.17.20:
|
||||
@ -4239,6 +4283,13 @@ packages:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
|
||||
/resolve/1.20.0:
|
||||
dependencies:
|
||||
is-core-module: 2.2.0
|
||||
path-parse: 1.0.6
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
/responselike/1.0.2:
|
||||
dependencies:
|
||||
lowercase-keys: 1.0.1
|
||||
@ -4781,6 +4832,7 @@ packages:
|
||||
/tr46/2.0.2:
|
||||
dependencies:
|
||||
punycode: 2.1.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
@ -5015,6 +5067,7 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
|
||||
/webidl-conversions/6.1.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=10.4'
|
||||
resolution:
|
||||
|
Loading…
Reference in New Issue
Block a user