Enhance EJS_STORAGE and EJS_Cache to support optional indexing for improved data retrieval

This commit is contained in:
Michael Green 2025-11-22 20:38:58 +11:00
parent 56bb0035f5
commit 406b2edba1
2 changed files with 56 additions and 9 deletions

View File

@ -41,17 +41,27 @@ class EJS_Cache {
if (this.storage && this.blobStorage) return;
return new Promise((resolve, reject) => {
const indexes = ["type", "url"];
const request = window.indexedDB.open(this.databaseName, 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Create object stores
db.createObjectStore("cache");
// Create metadata stores
const cacheStore = db.createObjectStore("cache");
// Create indexes for cache store if indexes array is present
if (Array.isArray(indexes)) {
for (const idx of indexes) {
if (!cacheStore.indexNames.contains(idx)) {
cacheStore.createIndex(idx, idx, { unique: false });
}
}
}
// Create blobs store
db.createObjectStore("blobs");
};
request.onsuccess = (event) => {
this.storage = new EJS_STORAGE(this.databaseName, "cache");
this.storage = new EJS_STORAGE(this.databaseName, "cache", indexes);
this.blobStorage = new EJS_STORAGE(this.databaseName, "blobs");
resolve();
};

View File

@ -1,7 +1,13 @@
class EJS_STORAGE {
constructor(dbName, storeName) {
/**
* @param {string} dbName
* @param {string} storeName
* @param {string[]?} indexes - Optional array of field names to create non-unique indexes on
*/
constructor(dbName, storeName, indexes = null) {
this.dbName = dbName;
this.storeName = storeName;
this.indexes = indexes;
}
#addFileToDB(key, add) {
(async () => {
@ -30,19 +36,50 @@ class EJS_STORAGE {
};
openRequest.onupgradeneeded = () => {
let db = openRequest.result;
let objectStore;
if (!db.objectStoreNames.contains(this.storeName)) {
db.createObjectStore(this.storeName);
objectStore = db.createObjectStore(this.storeName);
} else {
objectStore = openRequest.transaction.objectStore(this.storeName);
}
// Create indexes if provided
if (this.indexes && Array.isArray(this.indexes)) {
for (const idx of this.indexes) {
if (!objectStore.indexNames.contains(idx)) {
objectStore.createIndex(idx, idx, { unique: false });
}
}
}
};
});
}
get(key) {
/**
* Get a value by key or by index.
* @param {string|any} key - The key or index value to search for
* @param {string|null} indexName - Optional index name to search by
* @returns {Promise<any>}
*/
get(key, indexName = null) {
return new Promise(async (resolve, reject) => {
const objectStore = await this.#getObjectStore();
if (!objectStore) return resolve();
let request = objectStore.get(key);
request.onsuccess = () => resolve(request.result);
request.onerror = () => resolve();
if (!indexName) {
// Default: get by primary key
let request = objectStore.get(key);
request.onsuccess = () => resolve(request.result);
request.onerror = () => resolve();
} else {
// Get by index
try {
const index = objectStore.index(indexName);
let req = index.get(key);
req.onsuccess = () => resolve(req.result);
req.onerror = () => resolve();
} catch (e) {
// Index not found
resolve();
}
}
});
}
put(key, data) {