indexeddb?
This commit is contained in:
168
project-warstone/src/utils/indexeddb.ts
Normal file
168
project-warstone/src/utils/indexeddb.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
class IndexedDBService {
|
||||
private dbName: string;
|
||||
private dbVersion: number;
|
||||
private storeNames: string[];
|
||||
private db: IDBDatabase | null = null;
|
||||
|
||||
constructor(dbName: string, dbVersion: number, storeNames: string[]) {
|
||||
this.dbName = dbName;
|
||||
this.dbVersion = dbVersion;
|
||||
this.storeNames = storeNames;
|
||||
}
|
||||
|
||||
private async openDB(): Promise<IDBDatabase> {
|
||||
if (this.db) return this.db;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(this.dbName, this.dbVersion);
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to open the database.'));
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
resolve(this.db);
|
||||
};
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = (event.target as IDBOpenDBRequest).result;
|
||||
|
||||
// Create all the required object stores during the upgrade
|
||||
for (const storeName of this.storeNames) {
|
||||
if (!db.objectStoreNames.contains(storeName)) {
|
||||
db.createObjectStore(storeName, { keyPath: 'uuid' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
request.onblocked = () => {
|
||||
reject(new Error('Database is blocked and cannot be accessed.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private generateUUID(): string {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
public async create(data: any): Promise<string> {
|
||||
const db = await this.openDB();
|
||||
const uuid = this.generateUUID();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(data.storeName, 'readwrite');
|
||||
const objectStore = transaction.objectStore(data.storeName);
|
||||
|
||||
const request = objectStore.add({ ...data, uuid });
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve(uuid);
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to add data to IndexedDB.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async read(storeName: string, uuid: string): Promise<any | null> {
|
||||
const db = await this.openDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(storeName, 'readonly');
|
||||
const objectStore = transaction.objectStore(storeName);
|
||||
|
||||
const request = objectStore.get(uuid);
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve(request.result);
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to read data from IndexedDB.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async update(storeName: string, uuid: string, newData: any): Promise<void> {
|
||||
const db = await this.openDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(storeName, 'readwrite');
|
||||
const objectStore = transaction.objectStore(storeName);
|
||||
|
||||
const request = objectStore.put({ ...newData, uuid }, uuid);
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to update data in IndexedDB.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async delete(storeName: string, uuid: string): Promise<void> {
|
||||
const db = await this.openDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(storeName, 'readwrite');
|
||||
const objectStore = transaction.objectStore(storeName);
|
||||
|
||||
const request = objectStore.delete(uuid);
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to delete data from IndexedDB.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async listAll(storeName: string, fieldName: string): Promise<[string, any][]> {
|
||||
const db = await this.openDB();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(storeName, 'readonly');
|
||||
const objectStore = transaction.objectStore(storeName);
|
||||
const request = objectStore.openCursor();
|
||||
|
||||
const results: [string, any][] = [];
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
const cursor: IDBCursorWithValue = (event.target as IDBRequest).result;
|
||||
if (cursor) {
|
||||
const data = cursor.value;
|
||||
if (fieldName in data) {
|
||||
results.push([data.uuid, data[fieldName]]);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
resolve(results);
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
reject(new Error('Failed to list data from IndexedDB.'));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async createOrUpdate(data: any): Promise<string> {
|
||||
const db = await this.openDB();
|
||||
|
||||
// If the provided data already has a UUID, check if it exists in the database
|
||||
if (data.uuid) {
|
||||
const existingData = await this.read(data.storeName, data.uuid);
|
||||
if (existingData) {
|
||||
await this.update(data.storeName, data.uuid, data);
|
||||
return data.uuid;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a new UUID for the data and use the create method
|
||||
const uuid = this.generateUUID();
|
||||
await this.create({ ...data, uuid, storeName: data.storeName });
|
||||
return uuid;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user