idb-bridge: indexes belong to object stores
This commit is contained in:
parent
3263d05ce9
commit
d947b90df3
@ -44,7 +44,7 @@ export class BridgeIDBFactory {
|
|||||||
|
|
||||||
queueTask(async () => {
|
queueTask(async () => {
|
||||||
const databases = await this.backend.getDatabases();
|
const databases = await this.backend.getDatabases();
|
||||||
const dbInfo = databases.find((x) => x.name == name);
|
const dbInfo = databases.find(x => x.name == name);
|
||||||
if (!dbInfo) {
|
if (!dbInfo) {
|
||||||
// Database already doesn't exist, success!
|
// Database already doesn't exist, success!
|
||||||
const event = new BridgeIDBVersionChangeEvent("success", {
|
const event = new BridgeIDBVersionChangeEvent("success", {
|
||||||
@ -58,7 +58,10 @@ export class BridgeIDBFactory {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const dbconn = await this.backend.connectDatabase(name);
|
const dbconn = await this.backend.connectDatabase(name);
|
||||||
const backendTransaction = await this.backend.enterVersionChange(dbconn, 0);
|
const backendTransaction = await this.backend.enterVersionChange(
|
||||||
|
dbconn,
|
||||||
|
0,
|
||||||
|
);
|
||||||
await this.backend.deleteDatabase(backendTransaction, name);
|
await this.backend.deleteDatabase(backendTransaction, name);
|
||||||
await this.backend.commit(backendTransaction);
|
await this.backend.commit(backendTransaction);
|
||||||
await this.backend.close(dbconn);
|
await this.backend.close(dbconn);
|
||||||
@ -120,6 +123,11 @@ export class BridgeIDBFactory {
|
|||||||
|
|
||||||
const requestedVersion = version;
|
const requestedVersion = version;
|
||||||
|
|
||||||
|
BridgeIDBFactory.enableTracing &&
|
||||||
|
console.log(
|
||||||
|
`TRACE: existing version ${existingVersion}, requested version ${requestedVersion}`,
|
||||||
|
);
|
||||||
|
|
||||||
if (existingVersion > requestedVersion) {
|
if (existingVersion > requestedVersion) {
|
||||||
request._finishWithError(new VersionError());
|
request._finishWithError(new VersionError());
|
||||||
return;
|
return;
|
||||||
@ -127,6 +135,18 @@ export class BridgeIDBFactory {
|
|||||||
|
|
||||||
const db = new BridgeIDBDatabase(this.backend, dbconn);
|
const db = new BridgeIDBDatabase(this.backend, dbconn);
|
||||||
|
|
||||||
|
if (existingVersion == requestedVersion) {
|
||||||
|
request.result = db;
|
||||||
|
request.readyState = "done";
|
||||||
|
|
||||||
|
const event2 = new FakeEvent("success", {
|
||||||
|
bubbles: false,
|
||||||
|
cancelable: false,
|
||||||
|
});
|
||||||
|
event2.eventPath = [request];
|
||||||
|
request.dispatchEvent(event2);
|
||||||
|
}
|
||||||
|
|
||||||
if (existingVersion < requestedVersion) {
|
if (existingVersion < requestedVersion) {
|
||||||
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#dfn-steps-for-running-a-versionchange-transaction
|
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#dfn-steps-for-running-a-versionchange-transaction
|
||||||
|
|
||||||
@ -146,7 +166,10 @@ export class BridgeIDBFactory {
|
|||||||
request.dispatchEvent(event);
|
request.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
const backendTransaction = await this.backend.enterVersionChange(dbconn, requestedVersion);
|
const backendTransaction = await this.backend.enterVersionChange(
|
||||||
|
dbconn,
|
||||||
|
requestedVersion,
|
||||||
|
);
|
||||||
db._runningVersionchangeTransaction = true;
|
db._runningVersionchangeTransaction = true;
|
||||||
|
|
||||||
const transaction = db._internalTransaction(
|
const transaction = db._internalTransaction(
|
||||||
|
@ -59,15 +59,15 @@ export class BridgeIDBIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get keyPath(): KeyPath {
|
get keyPath(): KeyPath {
|
||||||
return this._schema.indexes[this._name].keyPath;
|
return this._schema.objectStores[this.objectStore.name].indexes[this._name].keyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
get multiEntry(): boolean {
|
get multiEntry(): boolean {
|
||||||
return this._schema.indexes[this._name].multiEntry;
|
return this._schema.objectStores[this.objectStore.name].indexes[this._name].multiEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
get unique(): boolean {
|
get unique(): boolean {
|
||||||
return this._schema.indexes[this._name].unique;
|
return this._schema.objectStores[this.objectStore.name].indexes[this._name].unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
get _backend(): Backend {
|
get _backend(): Backend {
|
||||||
@ -112,7 +112,7 @@ export class BridgeIDBIndex {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._backend.renameIndex(btx, oldName, newName);
|
this._backend.renameIndex(btx, this.objectStore.name, oldName, newName);
|
||||||
|
|
||||||
if (this.objectStore.indexNames.indexOf(name) >= 0) {
|
if (this.objectStore.indexNames.indexOf(name) >= 0) {
|
||||||
throw new ConstraintError();
|
throw new ConstraintError();
|
||||||
|
@ -63,7 +63,7 @@ class BridgeIDBObjectStore {
|
|||||||
|
|
||||||
get indexNames(): FakeDOMStringList {
|
get indexNames(): FakeDOMStringList {
|
||||||
return fakeDOMStringList(
|
return fakeDOMStringList(
|
||||||
this._schema.objectStores[this._name].indexes,
|
Object.keys(this._schema.objectStores[this._name].indexes),
|
||||||
).sort();
|
).sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ class BridgeIDBObjectStore {
|
|||||||
return new BridgeIDBIndex(this, name);
|
return new BridgeIDBIndex(this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteIndex(name: string) {
|
public deleteIndex(indexName: string) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
throw new TypeError();
|
throw new TypeError();
|
||||||
}
|
}
|
||||||
@ -419,12 +419,12 @@ class BridgeIDBObjectStore {
|
|||||||
|
|
||||||
const { btx } = this._confirmActiveTransaction();
|
const { btx } = this._confirmActiveTransaction();
|
||||||
|
|
||||||
const index = this._indexesCache.get(name);
|
const index = this._indexesCache.get(indexName);
|
||||||
if (index !== undefined) {
|
if (index !== undefined) {
|
||||||
index._deleted = true;
|
index._deleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._backend.deleteIndex(btx, name);
|
this._backend.deleteIndex(btx, this._name, indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBObjectStore-count-IDBRequest-any-key
|
// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBObjectStore-count-IDBRequest-any-key
|
||||||
|
@ -57,6 +57,8 @@ interface ObjectStore {
|
|||||||
deleted: boolean;
|
deleted: boolean;
|
||||||
originalKeyGenerator: number;
|
originalKeyGenerator: number;
|
||||||
modifiedKeyGenerator: number | undefined;
|
modifiedKeyGenerator: number | undefined;
|
||||||
|
committedIndexes: { [name: string]: Index };
|
||||||
|
modifiedIndexes: { [name: string]: Index };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Index {
|
interface Index {
|
||||||
@ -70,8 +72,6 @@ interface Index {
|
|||||||
interface Database {
|
interface Database {
|
||||||
committedObjectStores: { [name: string]: ObjectStore };
|
committedObjectStores: { [name: string]: ObjectStore };
|
||||||
modifiedObjectStores: { [name: string]: ObjectStore };
|
modifiedObjectStores: { [name: string]: ObjectStore };
|
||||||
committedIndexes: { [name: string]: Index };
|
|
||||||
modifiedIndexes: { [name: string]: Index };
|
|
||||||
committedSchema: Schema;
|
committedSchema: Schema;
|
||||||
/**
|
/**
|
||||||
* Was the transaction deleted during the running transaction?
|
* Was the transaction deleted during the running transaction?
|
||||||
@ -83,27 +83,32 @@ interface Database {
|
|||||||
connectionCookie: string | undefined;
|
connectionCookie: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ObjectStoreDump {
|
|
||||||
name: string;
|
|
||||||
keyGenerator: number;
|
|
||||||
records: ObjectStoreRecord[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IndexDump {
|
interface IndexDump {
|
||||||
name: string;
|
name: string;
|
||||||
records: IndexRecord[];
|
records: IndexRecord[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ObjectStoreDump {
|
||||||
|
name: string;
|
||||||
|
keyGenerator: number;
|
||||||
|
records: ObjectStoreRecord[];
|
||||||
|
indexes: { [name: string]: IndexDump };
|
||||||
|
}
|
||||||
|
|
||||||
interface DatabaseDump {
|
interface DatabaseDump {
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
objectStores: { [name: string]: ObjectStoreDump };
|
objectStores: { [name: string]: ObjectStoreDump };
|
||||||
indexes: { [name: string]: IndexDump };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MemoryBackendDump {
|
interface MemoryBackendDump {
|
||||||
databases: { [name: string]: DatabaseDump };
|
databases: { [name: string]: DatabaseDump };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ObjectStoreMapEntry {
|
||||||
|
store: ObjectStore;
|
||||||
|
indexMap: { [currentName: string]: Index };
|
||||||
|
}
|
||||||
|
|
||||||
interface Connection {
|
interface Connection {
|
||||||
dbName: string;
|
dbName: string;
|
||||||
|
|
||||||
@ -118,8 +123,7 @@ interface Connection {
|
|||||||
* Map from the effective name of an object store during
|
* Map from the effective name of an object store during
|
||||||
* the transaction to the real name.
|
* the transaction to the real name.
|
||||||
*/
|
*/
|
||||||
objectStoreMap: { [currentName: string]: ObjectStore };
|
objectStoreMap: { [currentName: string]: ObjectStoreMapEntry };
|
||||||
indexMap: { [currentName: string]: Index };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IndexRecord {
|
interface IndexRecord {
|
||||||
@ -253,25 +257,27 @@ export class MemoryBackend implements Backend {
|
|||||||
if (typeof schema !== "object") {
|
if (typeof schema !== "object") {
|
||||||
throw Error("DB dump corrupt");
|
throw Error("DB dump corrupt");
|
||||||
}
|
}
|
||||||
const indexes: { [name: string]: Index } = {};
|
|
||||||
const objectStores: { [name: string]: ObjectStore } = {};
|
const objectStores: { [name: string]: ObjectStore } = {};
|
||||||
for (const indexName of Object.keys(data.databases[dbName].indexes)) {
|
|
||||||
const dumpedIndex = data.databases[dbName].indexes[indexName];
|
|
||||||
const pairs = dumpedIndex.records.map((r: any) => {
|
|
||||||
return structuredClone([r.indexKey, r]);
|
|
||||||
});
|
|
||||||
const indexData: ISortedMapF<Key, IndexRecord> = new BTree(pairs, compareKeys);
|
|
||||||
const index: Index = {
|
|
||||||
deleted: false,
|
|
||||||
modifiedData: undefined,
|
|
||||||
modifiedName: undefined,
|
|
||||||
originalName: indexName,
|
|
||||||
originalData: indexData,
|
|
||||||
}
|
|
||||||
indexes[indexName] = index;
|
|
||||||
}
|
|
||||||
for (const objectStoreName of Object.keys(data.databases[dbName].objectStores)) {
|
for (const objectStoreName of Object.keys(data.databases[dbName].objectStores)) {
|
||||||
const dumpedObjectStore = data.databases[dbName].objectStores[objectStoreName];
|
const dumpedObjectStore = data.databases[dbName].objectStores[objectStoreName];
|
||||||
|
|
||||||
|
const indexes: { [name: string]: Index } = {};
|
||||||
|
for (const indexName of Object.keys(dumpedObjectStore.indexes)) {
|
||||||
|
const dumpedIndex = dumpedObjectStore.indexes[indexName];
|
||||||
|
const pairs = dumpedIndex.records.map((r: any) => {
|
||||||
|
return structuredClone([r.indexKey, r]);
|
||||||
|
});
|
||||||
|
const indexData: ISortedMapF<Key, IndexRecord> = new BTree(pairs, compareKeys);
|
||||||
|
const index: Index = {
|
||||||
|
deleted: false,
|
||||||
|
modifiedData: undefined,
|
||||||
|
modifiedName: undefined,
|
||||||
|
originalName: indexName,
|
||||||
|
originalData: indexData,
|
||||||
|
}
|
||||||
|
indexes[indexName] = index;
|
||||||
|
}
|
||||||
|
|
||||||
const pairs = dumpedObjectStore.records.map((r: any) => {
|
const pairs = dumpedObjectStore.records.map((r: any) => {
|
||||||
return structuredClone([r.primaryKey, r]);
|
return structuredClone([r.primaryKey, r]);
|
||||||
});
|
});
|
||||||
@ -284,16 +290,16 @@ export class MemoryBackend implements Backend {
|
|||||||
originalData: objectStoreData,
|
originalData: objectStoreData,
|
||||||
originalName: objectStoreName,
|
originalName: objectStoreName,
|
||||||
originalKeyGenerator: dumpedObjectStore.keyGenerator,
|
originalKeyGenerator: dumpedObjectStore.keyGenerator,
|
||||||
|
committedIndexes: indexes,
|
||||||
|
modifiedIndexes: {},
|
||||||
}
|
}
|
||||||
objectStores[objectStoreName] = objectStore;
|
objectStores[objectStoreName] = objectStore;
|
||||||
}
|
}
|
||||||
const db: Database = {
|
const db: Database = {
|
||||||
committedIndexes: indexes,
|
|
||||||
deleted: false,
|
deleted: false,
|
||||||
committedObjectStores: objectStores,
|
committedObjectStores: objectStores,
|
||||||
committedSchema: structuredClone(schema),
|
committedSchema: structuredClone(schema),
|
||||||
connectionCookie: undefined,
|
connectionCookie: undefined,
|
||||||
modifiedIndexes: {},
|
|
||||||
modifiedObjectStores: {},
|
modifiedObjectStores: {},
|
||||||
txLevel: TransactionLevel.Disconnected,
|
txLevel: TransactionLevel.Disconnected,
|
||||||
};
|
};
|
||||||
@ -301,6 +307,19 @@ export class MemoryBackend implements Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private makeObjectStoreMap(database: Database): { [currentName: string]: ObjectStoreMapEntry } {
|
||||||
|
let map: { [currentName: string]: ObjectStoreMapEntry } = {}
|
||||||
|
for (let objectStoreName in database.committedObjectStores) {
|
||||||
|
const store = database.committedObjectStores[objectStoreName];
|
||||||
|
const entry: ObjectStoreMapEntry = {
|
||||||
|
store,
|
||||||
|
indexMap: Object.assign({}, store.committedIndexes)
|
||||||
|
};
|
||||||
|
map[objectStoreName] = entry;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export the contents of the database to JSON.
|
* Export the contents of the database to JSON.
|
||||||
*
|
*
|
||||||
@ -310,18 +329,19 @@ export class MemoryBackend implements Backend {
|
|||||||
const dbDumps: { [name: string]: DatabaseDump } = {};
|
const dbDumps: { [name: string]: DatabaseDump } = {};
|
||||||
for (const dbName of Object.keys(this.databases)) {
|
for (const dbName of Object.keys(this.databases)) {
|
||||||
const db = this.databases[dbName];
|
const db = this.databases[dbName];
|
||||||
const indexes: { [name: string]: IndexDump } = {};
|
|
||||||
const objectStores: { [name: string]: ObjectStoreDump } = {};
|
const objectStores: { [name: string]: ObjectStoreDump } = {};
|
||||||
for (const indexName of Object.keys(db.committedIndexes)) {
|
|
||||||
const index = db.committedIndexes[indexName];
|
|
||||||
const indexRecords: IndexRecord[] = [];
|
|
||||||
index.originalData.forEach((v: IndexRecord) => {
|
|
||||||
indexRecords.push(structuredClone(v));
|
|
||||||
});
|
|
||||||
indexes[indexName] = { name: indexName, records: indexRecords };
|
|
||||||
}
|
|
||||||
for (const objectStoreName of Object.keys(db.committedObjectStores)) {
|
for (const objectStoreName of Object.keys(db.committedObjectStores)) {
|
||||||
const objectStore = db.committedObjectStores[objectStoreName];
|
const objectStore = db.committedObjectStores[objectStoreName];
|
||||||
|
|
||||||
|
const indexes: { [name: string]: IndexDump } = {};
|
||||||
|
for (const indexName of Object.keys(objectStore.committedIndexes)) {
|
||||||
|
const index = objectStore.committedIndexes[indexName];
|
||||||
|
const indexRecords: IndexRecord[] = [];
|
||||||
|
index.originalData.forEach((v: IndexRecord) => {
|
||||||
|
indexRecords.push(structuredClone(v));
|
||||||
|
});
|
||||||
|
indexes[indexName] = { name: indexName, records: indexRecords };
|
||||||
|
}
|
||||||
const objectStoreRecords: ObjectStoreRecord[] = [];
|
const objectStoreRecords: ObjectStoreRecord[] = [];
|
||||||
objectStore.originalData.forEach((v: ObjectStoreRecord) => {
|
objectStore.originalData.forEach((v: ObjectStoreRecord) => {
|
||||||
objectStoreRecords.push(structuredClone(v));
|
objectStoreRecords.push(structuredClone(v));
|
||||||
@ -330,10 +350,10 @@ export class MemoryBackend implements Backend {
|
|||||||
name: objectStoreName,
|
name: objectStoreName,
|
||||||
records: objectStoreRecords,
|
records: objectStoreRecords,
|
||||||
keyGenerator: objectStore.originalKeyGenerator,
|
keyGenerator: objectStore.originalKeyGenerator,
|
||||||
|
indexes: indexes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const dbDump: DatabaseDump = {
|
const dbDump: DatabaseDump = {
|
||||||
indexes,
|
|
||||||
objectStores,
|
objectStores,
|
||||||
schema: structuredClone(this.databases[dbName].committedSchema),
|
schema: structuredClone(this.databases[dbName].committedSchema),
|
||||||
};
|
};
|
||||||
@ -391,15 +411,12 @@ export class MemoryBackend implements Backend {
|
|||||||
if (!database) {
|
if (!database) {
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
databaseName: name,
|
databaseName: name,
|
||||||
indexes: {},
|
|
||||||
databaseVersion: 0,
|
databaseVersion: 0,
|
||||||
objectStores: {},
|
objectStores: {},
|
||||||
};
|
};
|
||||||
database = {
|
database = {
|
||||||
committedSchema: schema,
|
committedSchema: schema,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
modifiedIndexes: {},
|
|
||||||
committedIndexes: {},
|
|
||||||
committedObjectStores: {},
|
committedObjectStores: {},
|
||||||
modifiedObjectStores: {},
|
modifiedObjectStores: {},
|
||||||
txLevel: TransactionLevel.Disconnected,
|
txLevel: TransactionLevel.Disconnected,
|
||||||
@ -418,8 +435,7 @@ export class MemoryBackend implements Backend {
|
|||||||
const myConn: Connection = {
|
const myConn: Connection = {
|
||||||
dbName: name,
|
dbName: name,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
indexMap: Object.assign({}, database.committedIndexes),
|
objectStoreMap: this.makeObjectStoreMap(database),
|
||||||
objectStoreMap: Object.assign({}, database.committedObjectStores),
|
|
||||||
modifiedSchema: structuredClone(database.committedSchema),
|
modifiedSchema: structuredClone(database.committedSchema),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -532,6 +548,7 @@ export class MemoryBackend implements Backend {
|
|||||||
|
|
||||||
renameIndex(
|
renameIndex(
|
||||||
btx: DatabaseTransaction,
|
btx: DatabaseTransaction,
|
||||||
|
objectStoreName: string,
|
||||||
oldName: string,
|
oldName: string,
|
||||||
newName: string,
|
newName: string,
|
||||||
): void {
|
): void {
|
||||||
@ -553,34 +570,25 @@ export class MemoryBackend implements Backend {
|
|||||||
if (!schema) {
|
if (!schema) {
|
||||||
throw Error();
|
throw Error();
|
||||||
}
|
}
|
||||||
if (schema.indexes[newName]) {
|
const indexesSchema = schema.objectStores[objectStoreName].indexes;
|
||||||
|
if (indexesSchema[newName]) {
|
||||||
throw new Error("new index name already used");
|
throw new Error("new index name already used");
|
||||||
}
|
}
|
||||||
if (!schema.indexes[oldName]) {
|
if (!indexesSchema) {
|
||||||
throw new Error("new index name already used");
|
throw new Error("new index name already used");
|
||||||
}
|
}
|
||||||
const index: Index = myConn.indexMap[oldName];
|
const index: Index = myConn.objectStoreMap[objectStoreName].indexMap[oldName];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
throw Error("old index missing in connection's index map");
|
throw Error("old index missing in connection's index map");
|
||||||
}
|
}
|
||||||
schema.indexes[newName] = schema.indexes[newName];
|
indexesSchema[newName] = indexesSchema[newName];
|
||||||
delete schema.indexes[oldName];
|
delete indexesSchema[oldName];
|
||||||
for (const storeName in schema.objectStores) {
|
myConn.objectStoreMap[objectStoreName].indexMap[newName] = index;
|
||||||
const store = schema.objectStores[storeName];
|
delete myConn.objectStoreMap[objectStoreName].indexMap[oldName];
|
||||||
store.indexes = store.indexes.map(x => {
|
|
||||||
if (x == oldName) {
|
|
||||||
return newName;
|
|
||||||
} else {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
myConn.indexMap[newName] = index;
|
|
||||||
delete myConn.indexMap[oldName];
|
|
||||||
index.modifiedName = newName;
|
index.modifiedName = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteIndex(btx: DatabaseTransaction, indexName: string): void {
|
deleteIndex(btx: DatabaseTransaction, objectStoreName: string, indexName: string): void {
|
||||||
if (this.enableTracing) {
|
if (this.enableTracing) {
|
||||||
console.log(`TRACING: deleteIndex(${indexName})`);
|
console.log(`TRACING: deleteIndex(${indexName})`);
|
||||||
}
|
}
|
||||||
@ -599,22 +607,16 @@ export class MemoryBackend implements Backend {
|
|||||||
if (!schema) {
|
if (!schema) {
|
||||||
throw Error();
|
throw Error();
|
||||||
}
|
}
|
||||||
if (!schema.indexes[indexName]) {
|
if (!schema.objectStores[objectStoreName].indexes[indexName]) {
|
||||||
throw new Error("index does not exist");
|
throw new Error("index does not exist");
|
||||||
}
|
}
|
||||||
const index: Index = myConn.indexMap[indexName];
|
const index: Index = myConn.objectStoreMap[objectStoreName].indexMap[indexName];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
throw Error("old index missing in connection's index map");
|
throw Error("old index missing in connection's index map");
|
||||||
}
|
}
|
||||||
index.deleted = true;
|
index.deleted = true;
|
||||||
delete schema.indexes[indexName];
|
delete schema.objectStores[objectStoreName].indexes[indexName];
|
||||||
delete myConn.indexMap[indexName];
|
delete myConn.objectStoreMap[objectStoreName].indexMap[indexName];
|
||||||
for (const storeName in schema.objectStores) {
|
|
||||||
const store = schema.objectStores[storeName];
|
|
||||||
store.indexes = store.indexes.filter(x => {
|
|
||||||
return x !== indexName;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteObjectStore(btx: DatabaseTransaction, name: string): void {
|
deleteObjectStore(btx: DatabaseTransaction, name: string): void {
|
||||||
@ -640,16 +642,16 @@ export class MemoryBackend implements Backend {
|
|||||||
if (!objectStoreProperties) {
|
if (!objectStoreProperties) {
|
||||||
throw Error("object store not found");
|
throw Error("object store not found");
|
||||||
}
|
}
|
||||||
const objectStore = myConn.objectStoreMap[name];
|
const objectStoreMapEntry = myConn.objectStoreMap[name];
|
||||||
if (!objectStore) {
|
if (!objectStoreMapEntry) {
|
||||||
throw Error("object store not found in map");
|
throw Error("object store not found in map");
|
||||||
}
|
}
|
||||||
const indexNames = objectStoreProperties.indexes;
|
const indexNames = Object.keys(objectStoreProperties.indexes);
|
||||||
for (const indexName of indexNames) {
|
for (const indexName of indexNames) {
|
||||||
this.deleteIndex(btx, indexName);
|
this.deleteIndex(btx, name, indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
objectStore.deleted = true;
|
objectStoreMapEntry.store.deleted = true;
|
||||||
delete myConn.objectStoreMap[name];
|
delete myConn.objectStoreMap[name];
|
||||||
delete schema.objectStores[name];
|
delete schema.objectStores[name];
|
||||||
}
|
}
|
||||||
@ -684,15 +686,15 @@ export class MemoryBackend implements Backend {
|
|||||||
if (schema.objectStores[newName]) {
|
if (schema.objectStores[newName]) {
|
||||||
throw Error("new object store already exists");
|
throw Error("new object store already exists");
|
||||||
}
|
}
|
||||||
const objectStore = myConn.objectStoreMap[oldName];
|
const objectStoreMapEntry = myConn.objectStoreMap[oldName];
|
||||||
if (!objectStore) {
|
if (!objectStoreMapEntry) {
|
||||||
throw Error("object store not found in map");
|
throw Error("object store not found in map");
|
||||||
}
|
}
|
||||||
objectStore.modifiedName = newName;
|
objectStoreMapEntry.store.modifiedName = newName;
|
||||||
schema.objectStores[newName] = schema.objectStores[oldName];
|
schema.objectStores[newName] = schema.objectStores[oldName];
|
||||||
delete schema.objectStores[oldName];
|
delete schema.objectStores[oldName];
|
||||||
delete myConn.objectStoreMap[oldName];
|
delete myConn.objectStoreMap[oldName];
|
||||||
myConn.objectStoreMap[newName] = objectStore;
|
myConn.objectStoreMap[newName] = objectStoreMapEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
createObjectStore(
|
createObjectStore(
|
||||||
@ -725,6 +727,8 @@ export class MemoryBackend implements Backend {
|
|||||||
originalData: new BTree([], compareKeys),
|
originalData: new BTree([], compareKeys),
|
||||||
modifiedKeyGenerator: undefined,
|
modifiedKeyGenerator: undefined,
|
||||||
originalKeyGenerator: 1,
|
originalKeyGenerator: 1,
|
||||||
|
committedIndexes: {},
|
||||||
|
modifiedIndexes: {},
|
||||||
};
|
};
|
||||||
const schema = myConn.modifiedSchema;
|
const schema = myConn.modifiedSchema;
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
@ -733,9 +737,9 @@ export class MemoryBackend implements Backend {
|
|||||||
schema.objectStores[name] = {
|
schema.objectStores[name] = {
|
||||||
autoIncrement,
|
autoIncrement,
|
||||||
keyPath,
|
keyPath,
|
||||||
indexes: [],
|
indexes: {},
|
||||||
};
|
};
|
||||||
myConn.objectStoreMap[name] = newObjectStore;
|
myConn.objectStoreMap[name] = { store: newObjectStore, indexMap: {} };
|
||||||
db.modifiedObjectStores[name] = newObjectStore;
|
db.modifiedObjectStores[name] = newObjectStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,8 +777,8 @@ export class MemoryBackend implements Backend {
|
|||||||
originalData: new BTree([], compareKeys),
|
originalData: new BTree([], compareKeys),
|
||||||
originalName: indexName,
|
originalName: indexName,
|
||||||
};
|
};
|
||||||
myConn.indexMap[indexName] = newIndex;
|
myConn.objectStoreMap[objectStoreName].indexMap[indexName] = newIndex;
|
||||||
db.modifiedIndexes[indexName] = newIndex;
|
db.modifiedObjectStores[objectStoreName].modifiedIndexes[indexName] = newIndex;
|
||||||
const schema = myConn.modifiedSchema;
|
const schema = myConn.modifiedSchema;
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
throw Error("no schema in versionchange tx");
|
throw Error("no schema in versionchange tx");
|
||||||
@ -783,15 +787,14 @@ export class MemoryBackend implements Backend {
|
|||||||
if (!objectStoreProperties) {
|
if (!objectStoreProperties) {
|
||||||
throw Error("object store not found");
|
throw Error("object store not found");
|
||||||
}
|
}
|
||||||
objectStoreProperties.indexes.push(indexName);
|
objectStoreProperties.indexes[indexName] = indexProperties;
|
||||||
schema.indexes[indexName] = indexProperties;
|
|
||||||
|
|
||||||
const objectStore = myConn.objectStoreMap[objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[objectStoreName];
|
||||||
if (!objectStore) {
|
if (!objectStoreMapEntry) {
|
||||||
throw Error("object store does not exist");
|
throw Error("object store does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeData = objectStore.modifiedData || objectStore.originalData;
|
const storeData = objectStoreMapEntry.store.modifiedData || objectStoreMapEntry.store.originalData;
|
||||||
|
|
||||||
storeData.forEach((v, k) => {
|
storeData.forEach((v, k) => {
|
||||||
this.insertIntoIndex(newIndex, k, v.value, indexProperties);
|
this.insertIntoIndex(newIndex, k, v.value, indexProperties);
|
||||||
@ -827,13 +830,13 @@ export class MemoryBackend implements Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const schema = myConn.modifiedSchema;
|
const schema = myConn.modifiedSchema;
|
||||||
const objectStore = myConn.objectStoreMap[objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[objectStoreName];
|
||||||
|
|
||||||
if (!objectStore.modifiedData) {
|
if (!objectStoreMapEntry.store.modifiedData) {
|
||||||
objectStore.modifiedData = objectStore.originalData;
|
objectStoreMapEntry.store.modifiedData = objectStoreMapEntry.store.originalData;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modifiedData = objectStore.modifiedData;
|
let modifiedData = objectStoreMapEntry.store.modifiedData;
|
||||||
let currKey: Key | undefined;
|
let currKey: Key | undefined;
|
||||||
|
|
||||||
if (range.lower === undefined || range.lower === null) {
|
if (range.lower === undefined || range.lower === null) {
|
||||||
@ -870,12 +873,13 @@ export class MemoryBackend implements Backend {
|
|||||||
throw Error("assertion failed");
|
throw Error("assertion failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const indexName of schema.objectStores[objectStoreName].indexes) {
|
|
||||||
const index = myConn.indexMap[indexName];
|
for (const indexName of Object.keys(schema.objectStores[objectStoreName].indexes)) {
|
||||||
|
const index = myConn.objectStoreMap[objectStoreName].indexMap[indexName];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
throw Error("index referenced by object store does not exist");
|
throw Error("index referenced by object store does not exist");
|
||||||
}
|
}
|
||||||
const indexProperties = schema.indexes[indexName];
|
const indexProperties = schema.objectStores[objectStoreName].indexes[indexName];
|
||||||
this.deleteFromIndex(
|
this.deleteFromIndex(
|
||||||
index,
|
index,
|
||||||
storeEntry.primaryKey,
|
storeEntry.primaryKey,
|
||||||
@ -889,7 +893,7 @@ export class MemoryBackend implements Backend {
|
|||||||
currKey = modifiedData.nextHigherKey(currKey);
|
currKey = modifiedData.nextHigherKey(currKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
objectStore.modifiedData = modifiedData;
|
objectStoreMapEntry.store.modifiedData = modifiedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private deleteFromIndex(
|
private deleteFromIndex(
|
||||||
@ -951,8 +955,8 @@ export class MemoryBackend implements Backend {
|
|||||||
if (db.txLevel < TransactionLevel.Read) {
|
if (db.txLevel < TransactionLevel.Read) {
|
||||||
throw Error("only allowed while running a transaction");
|
throw Error("only allowed while running a transaction");
|
||||||
}
|
}
|
||||||
const objectStore = myConn.objectStoreMap[req.objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[req.objectStoreName];
|
||||||
if (!objectStore) {
|
if (!objectStoreMapEntry) {
|
||||||
throw Error("object store not found");
|
throw Error("object store not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,12 +989,12 @@ export class MemoryBackend implements Backend {
|
|||||||
const unique: boolean =
|
const unique: boolean =
|
||||||
req.direction === "prevunique" || req.direction === "nextunique";
|
req.direction === "prevunique" || req.direction === "nextunique";
|
||||||
|
|
||||||
const storeData = objectStore.modifiedData || objectStore.originalData;
|
const storeData = objectStoreMapEntry.store.modifiedData || objectStoreMapEntry.store.originalData;
|
||||||
|
|
||||||
const haveIndex = req.indexName !== undefined;
|
const haveIndex = req.indexName !== undefined;
|
||||||
|
|
||||||
if (haveIndex) {
|
if (haveIndex) {
|
||||||
const index = myConn.indexMap[req.indexName!];
|
const index = myConn.objectStoreMap[req.objectStoreName].indexMap[req.indexName!];
|
||||||
const indexData = index.modifiedData || index.originalData;
|
const indexData = index.modifiedData || index.originalData;
|
||||||
let indexPos = req.lastIndexPosition;
|
let indexPos = req.lastIndexPosition;
|
||||||
|
|
||||||
@ -1160,7 +1164,9 @@ export class MemoryBackend implements Backend {
|
|||||||
for (let i = 0; i < numResults; i++) {
|
for (let i = 0; i < numResults; i++) {
|
||||||
const result = storeData.get(primaryKeys[i]);
|
const result = storeData.get(primaryKeys[i]);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw Error("invariant violated");
|
console.error("invariant violated during read");
|
||||||
|
console.error("request was", req);
|
||||||
|
throw Error("invariant violated during read");
|
||||||
}
|
}
|
||||||
values.push(structuredClone(result.value));
|
values.push(structuredClone(result.value));
|
||||||
}
|
}
|
||||||
@ -1262,12 +1268,12 @@ export class MemoryBackend implements Backend {
|
|||||||
throw Error("only allowed while running a transaction");
|
throw Error("only allowed while running a transaction");
|
||||||
}
|
}
|
||||||
const schema = myConn.modifiedSchema;
|
const schema = myConn.modifiedSchema;
|
||||||
const objectStore = myConn.objectStoreMap[storeReq.objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[storeReq.objectStoreName];
|
||||||
|
|
||||||
if (!objectStore.modifiedData) {
|
if (!objectStoreMapEntry.store.modifiedData) {
|
||||||
objectStore.modifiedData = objectStore.originalData;
|
objectStoreMapEntry.store.modifiedData = objectStoreMapEntry.store.originalData;
|
||||||
}
|
}
|
||||||
const modifiedData = objectStore.modifiedData;
|
const modifiedData = objectStoreMapEntry.store.modifiedData;
|
||||||
|
|
||||||
let key;
|
let key;
|
||||||
let value;
|
let value;
|
||||||
@ -1277,7 +1283,7 @@ export class MemoryBackend implements Backend {
|
|||||||
throw Error("invalid update request (key not given)");
|
throw Error("invalid update request (key not given)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!objectStore.modifiedData.has(storeReq.key)) {
|
if (!objectStoreMapEntry.store.modifiedData.has(storeReq.key)) {
|
||||||
throw Error("invalid update request (record does not exist)");
|
throw Error("invalid update request (record does not exist)");
|
||||||
}
|
}
|
||||||
key = storeReq.key;
|
key = storeReq.key;
|
||||||
@ -1286,13 +1292,13 @@ export class MemoryBackend implements Backend {
|
|||||||
const storeKeyResult: StoreKeyResult = makeStoreKeyValue(
|
const storeKeyResult: StoreKeyResult = makeStoreKeyValue(
|
||||||
storeReq.value,
|
storeReq.value,
|
||||||
storeReq.key,
|
storeReq.key,
|
||||||
objectStore.modifiedKeyGenerator || objectStore.originalKeyGenerator,
|
objectStoreMapEntry.store.modifiedKeyGenerator || objectStoreMapEntry.store.originalKeyGenerator,
|
||||||
schema.objectStores[storeReq.objectStoreName].autoIncrement,
|
schema.objectStores[storeReq.objectStoreName].autoIncrement,
|
||||||
schema.objectStores[storeReq.objectStoreName].keyPath,
|
schema.objectStores[storeReq.objectStoreName].keyPath,
|
||||||
);
|
);
|
||||||
key = storeKeyResult.key;
|
key = storeKeyResult.key;
|
||||||
value = storeKeyResult.value;
|
value = storeKeyResult.value;
|
||||||
objectStore.modifiedKeyGenerator = storeKeyResult.updatedKeyGenerator;
|
objectStoreMapEntry.store.modifiedKeyGenerator = storeKeyResult.updatedKeyGenerator;
|
||||||
const hasKey = modifiedData.has(key);
|
const hasKey = modifiedData.has(key);
|
||||||
|
|
||||||
if (hasKey && storeReq.storeLevel !== StoreLevel.AllowOverwrite) {
|
if (hasKey && storeReq.storeLevel !== StoreLevel.AllowOverwrite) {
|
||||||
@ -1305,15 +1311,15 @@ export class MemoryBackend implements Backend {
|
|||||||
value: structuredClone(value),
|
value: structuredClone(value),
|
||||||
};
|
};
|
||||||
|
|
||||||
objectStore.modifiedData = modifiedData.with(key, objectStoreRecord, true);
|
objectStoreMapEntry.store.modifiedData = modifiedData.with(key, objectStoreRecord, true);
|
||||||
|
|
||||||
for (const indexName of schema.objectStores[storeReq.objectStoreName]
|
for (const indexName of Object.keys(schema.objectStores[storeReq.objectStoreName]
|
||||||
.indexes) {
|
.indexes)) {
|
||||||
const index = myConn.indexMap[indexName];
|
const index = myConn.objectStoreMap[storeReq.objectStoreName] .indexMap[indexName];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
throw Error("index referenced by object store does not exist");
|
throw Error("index referenced by object store does not exist");
|
||||||
}
|
}
|
||||||
const indexProperties = schema.indexes[indexName];
|
const indexProperties = schema.objectStores[storeReq.objectStoreName].indexes[indexName];
|
||||||
this.insertIntoIndex(index, key, value, indexProperties);
|
this.insertIntoIndex(index, key, value, indexProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,24 +1382,24 @@ export class MemoryBackend implements Backend {
|
|||||||
if (db.txLevel < TransactionLevel.Read) {
|
if (db.txLevel < TransactionLevel.Read) {
|
||||||
throw Error("only allowed while running a transaction");
|
throw Error("only allowed while running a transaction");
|
||||||
}
|
}
|
||||||
db.modifiedIndexes = {};
|
|
||||||
db.modifiedObjectStores = {};
|
db.modifiedObjectStores = {};
|
||||||
db.txLevel = TransactionLevel.Connected;
|
db.txLevel = TransactionLevel.Connected;
|
||||||
myConn.modifiedSchema = structuredClone(db.committedSchema);
|
myConn.modifiedSchema = structuredClone(db.committedSchema);
|
||||||
myConn.indexMap = Object.assign({}, db.committedIndexes);
|
myConn.objectStoreMap = this.makeObjectStoreMap(db);
|
||||||
myConn.objectStoreMap = Object.assign({}, db.committedObjectStores);
|
|
||||||
for (const indexName in db.committedIndexes) {
|
|
||||||
const index = db.committedIndexes[indexName];
|
|
||||||
index.deleted = false;
|
|
||||||
index.modifiedData = undefined;
|
|
||||||
index.modifiedName = undefined;
|
|
||||||
}
|
|
||||||
for (const objectStoreName in db.committedObjectStores) {
|
for (const objectStoreName in db.committedObjectStores) {
|
||||||
const objectStore = db.committedObjectStores[objectStoreName];
|
const objectStore = db.committedObjectStores[objectStoreName];
|
||||||
objectStore.deleted = false;
|
objectStore.deleted = false;
|
||||||
objectStore.modifiedData = undefined;
|
objectStore.modifiedData = undefined;
|
||||||
objectStore.modifiedName = undefined;
|
objectStore.modifiedName = undefined;
|
||||||
objectStore.modifiedKeyGenerator = undefined;
|
objectStore.modifiedKeyGenerator = undefined;
|
||||||
|
objectStore.modifiedIndexes = {}
|
||||||
|
|
||||||
|
for (const indexName in Object.keys(db.committedSchema.objectStores[objectStoreName].indexes)) {
|
||||||
|
const index = objectStore.committedIndexes[indexName];
|
||||||
|
index.deleted = false;
|
||||||
|
index.modifiedData = undefined;
|
||||||
|
index.modifiedName = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete this.connectionsByTransaction[btx.transactionCookie];
|
delete this.connectionsByTransaction[btx.transactionCookie];
|
||||||
this.transactionDoneCond.trigger();
|
this.transactionDoneCond.trigger();
|
||||||
@ -1419,34 +1425,32 @@ export class MemoryBackend implements Backend {
|
|||||||
db.committedSchema = structuredClone(myConn.modifiedSchema);
|
db.committedSchema = structuredClone(myConn.modifiedSchema);
|
||||||
db.txLevel = TransactionLevel.Connected;
|
db.txLevel = TransactionLevel.Connected;
|
||||||
|
|
||||||
db.committedIndexes = {};
|
|
||||||
db.committedObjectStores = {};
|
db.committedObjectStores = {};
|
||||||
db.modifiedIndexes = {};
|
|
||||||
db.committedObjectStores = {};
|
db.committedObjectStores = {};
|
||||||
|
|
||||||
for (const indexName in myConn.indexMap) {
|
|
||||||
const index = myConn.indexMap[indexName];
|
|
||||||
index.deleted = false;
|
|
||||||
index.originalData = index.modifiedData || index.originalData;
|
|
||||||
index.originalName = index.modifiedName || index.originalName;
|
|
||||||
db.committedIndexes[indexName] = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const objectStoreName in myConn.objectStoreMap) {
|
for (const objectStoreName in myConn.objectStoreMap) {
|
||||||
const objectStore = myConn.objectStoreMap[objectStoreName];
|
const objectStoreMapEntry = myConn.objectStoreMap[objectStoreName];
|
||||||
objectStore.deleted = false;
|
const store = objectStoreMapEntry.store;
|
||||||
objectStore.originalData =
|
store.deleted = false;
|
||||||
objectStore.modifiedData || objectStore.originalData;
|
store.originalData = store.modifiedData || store.originalData;
|
||||||
objectStore.originalName =
|
store.originalName = store.modifiedName || store.originalName;
|
||||||
objectStore.modifiedName || objectStore.originalName;
|
store.modifiedIndexes = {};
|
||||||
if (objectStore.modifiedKeyGenerator !== undefined) {
|
if (store.modifiedKeyGenerator !== undefined) {
|
||||||
objectStore.originalKeyGenerator = objectStore.modifiedKeyGenerator;
|
store.originalKeyGenerator = store.modifiedKeyGenerator;
|
||||||
}
|
}
|
||||||
db.committedObjectStores[objectStoreName] = objectStore;
|
db.committedObjectStores[objectStoreName] = store;
|
||||||
|
|
||||||
|
for (const indexName in objectStoreMapEntry.indexMap) {
|
||||||
|
const index = objectStoreMapEntry.indexMap[indexName];
|
||||||
|
index.deleted = false;
|
||||||
|
index.originalData = index.modifiedData || index.originalData;
|
||||||
|
index.originalName = index.modifiedName || index.originalName;
|
||||||
|
store.committedIndexes[indexName] = index;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myConn.indexMap = Object.assign({}, db.committedIndexes);
|
myConn.objectStoreMap = this.makeObjectStoreMap(db);
|
||||||
myConn.objectStoreMap = Object.assign({}, db.committedObjectStores);
|
|
||||||
|
|
||||||
delete this.connectionsByTransaction[btx.transactionCookie];
|
delete this.connectionsByTransaction[btx.transactionCookie];
|
||||||
this.transactionDoneCond.trigger();
|
this.transactionDoneCond.trigger();
|
||||||
|
@ -27,7 +27,7 @@ import BridgeIDBKeyRange from "./BridgeIDBKeyRange";
|
|||||||
export interface ObjectStoreProperties {
|
export interface ObjectStoreProperties {
|
||||||
keyPath: KeyPath | null;
|
keyPath: KeyPath | null;
|
||||||
autoIncrement: boolean;
|
autoIncrement: boolean;
|
||||||
indexes: string[];
|
indexes: { [nameame: string]: IndexProperties };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexProperties {
|
export interface IndexProperties {
|
||||||
@ -40,7 +40,6 @@ export interface Schema {
|
|||||||
databaseName: string;
|
databaseName: string;
|
||||||
databaseVersion: number;
|
databaseVersion: number;
|
||||||
objectStores: { [name: string]: ObjectStoreProperties };
|
objectStores: { [name: string]: ObjectStoreProperties };
|
||||||
indexes: { [name: string]: IndexProperties };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatabaseConnection {
|
export interface DatabaseConnection {
|
||||||
@ -153,9 +152,9 @@ export interface Backend {
|
|||||||
|
|
||||||
getSchema(db: DatabaseConnection): Schema;
|
getSchema(db: DatabaseConnection): Schema;
|
||||||
|
|
||||||
renameIndex(btx: DatabaseTransaction, oldName: string, newName: string): void;
|
renameIndex(btx: DatabaseTransaction, objectStoreName: string, oldName: string, newName: string): void;
|
||||||
|
|
||||||
deleteIndex(btx: DatabaseTransaction, indexName: string): void;
|
deleteIndex(btx: DatabaseTransaction, objectStoreName: string, indexName: string): void;
|
||||||
|
|
||||||
rollback(btx: DatabaseTransaction): Promise<void>;
|
rollback(btx: DatabaseTransaction): Promise<void>;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user