sdk_client/src/database.ts
2024-05-28 11:43:57 +02:00

179 lines
6.1 KiB
TypeScript

class Database {
private static instance: Database;
private db: IDBDatabase | null = null;
private dbName: string = '4nk';
private dbVersion: number = 1;
private storeDefinitions = {
AnkUser: {
name: "user",
options: {'keyPath': 'pre_id'},
indices: []
},
AnkSession: {
name: "session",
options: {},
indices: []
},
AnkProcess: {
name: "process",
options: {'keyPath': 'id'},
indices: [{
name: 'by_name',
keyPath: 'name',
options: {
'unique': true
}
}]
},
AnkMessages: {
name: "messages",
options: {'keyPath': 'id'},
indices: []
}
}
// Private constructor to prevent direct instantiation from outside
private constructor() {}
// Method to access the singleton instance of Database
public static async getInstance(): Promise<Database> {
if (!Database.instance) {
Database.instance = new Database();
await Database.instance.init();
}
return Database.instance;
}
// Initialize the database
private async init(): Promise<void> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, this.dbVersion);
request.onupgradeneeded = () => {
const db = request.result;
Object.values(this.storeDefinitions).forEach(({name, options, indices}) => {
if (!db.objectStoreNames.contains(name)) {
let store = db.createObjectStore(name, options);
indices.forEach(({name, keyPath, options}) => {
store.createIndex(name, keyPath, options);
})
}
});
};
request.onsuccess = () => {
this.db = request.result;
resolve();
};
request.onerror = () => {
console.error("Database error:", request.error);
reject(request.error);
};
});
}
public async getDb(): Promise<IDBDatabase> {
if (!this.db) {
await this.init();
}
return this.db!;
}
public getStoreList(): {[key: string]: string} {
const objectList: {[key: string]: string} = {};
Object.keys(this.storeDefinitions).forEach(key => {
objectList[key] = this.storeDefinitions[key as keyof typeof this.storeDefinitions].name;
});
return objectList;
}
public writeObject(db: IDBDatabase, storeName: string, obj: any, key: IDBValidKey | null): Promise<IDBRequest> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
let request: IDBRequest<any>;
if (key) {
request = store.add(obj, key);
} else {
request = store.add(obj);
}
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getObject<T>(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<T> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const request = store.get(key);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public rmObject(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<void> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.delete(key);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getFirstMatchWithIndex<T>(db: IDBDatabase, storeName: string, indexName: string, lookup: string): Promise<T | null> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const index = store.index(indexName);
const request = index.openCursor(IDBKeyRange.only(lookup));
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const cursor = request.result;
if (cursor) {
resolve(cursor.value);
} else {
resolve(null)
}
}
});
}
public setObject(db: IDBDatabase, storeName: string, obj: any, key: string | null): Promise<IDBRequest> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
let request: IDBRequest<any>;
if (key) {
request = store.put(obj, key);
} else {
request = store.put(obj);
}
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getAll<T>(db: IDBDatabase, storeName: string): Promise<T[]> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const request = store.getAll();
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
}
export default Database;