Skip to content

Commit

Permalink
comments
Browse files Browse the repository at this point in the history
  • Loading branch information
maximiliani committed Oct 31, 2024
1 parent 60ce8d5 commit d97c0f4
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions src/utils/IndexedDBUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import { DBSchema, openDB } from '@tempfix/idb';
const dbName: string = 'pid-component';
const dbVersion: number = undefined;

interface PIDComponentDB extends DBSchema {
/**
* The database schema for the PID component.
* @interface PIDComponentDB
* @extends DBSchema
*/
export interface PIDComponentDB extends DBSchema {
entities: {
key: string;
value: {
Expand Down Expand Up @@ -36,6 +41,11 @@ interface PIDComponentDB extends DBSchema {
};
}

/**
* Opens the indexedDB database for the PID component and creates the object stores and indexes if they do not exist.
* @type {Promise<IDBPDatabase<PIDComponentDB>>}
* @const
*/
const dbPromise = openDB<PIDComponentDB>(dbName, dbVersion, {
upgrade(db) {
const entityStore = db.createObjectStore('entities', {
Expand All @@ -46,16 +56,23 @@ const dbPromise = openDB<PIDComponentDB>(dbName, dbVersion, {
const relationStore = db.createObjectStore('relations', {
autoIncrement: true,
});

// Create indexes for the relations
relationStore.createIndex('by-start', 'start', { unique: false });
relationStore.createIndex('by-description', 'description', { unique: false });
relationStore.createIndex('by-end', 'end', { unique: false });
},
});

/**
* Adds an entity to the database.
* @param {GenericIdentifierType} renderer The renderer to add to the database.
*/
export async function addEntity(renderer: GenericIdentifierType) {
const context = document.documentURI;
const db = await dbPromise;

// Add the entity to the entities object store
await db
.add('entities', {
value: renderer.value,
Expand All @@ -71,16 +88,19 @@ export async function addEntity(renderer: GenericIdentifierType) {
});
console.debug('added entity', renderer);

// Add the relations to the relations object store
// Start a new transaction
const tx = db.transaction('relations', 'readwrite');
const promises = [];

for (const item of renderer.items) {
// Create a relation object
const relation = {
start: renderer.value,
description: item.keyTitle,
end: item.value,
// connectionType: "startToEnd"
};
// Check if the relation already exists
const index = tx.store.index('by-start');
let cursor = await index.openCursor();
while (cursor) {
Expand All @@ -90,13 +110,20 @@ export async function addEntity(renderer: GenericIdentifierType) {
}
cursor = await cursor.continue();
}
// Add the relation to the relations object store if it does not exist
promises.push(tx.store.add(relation));
}
promises.push(tx.done);
await Promise.all(promises);
console.debug('added relations', promises);
}

/**
* Gets an entity from the database. If the entity does not exist, it is created.
* @returns {Promise<GenericIdentifierType>} The renderer for the entity.
* @param {string} value The stringified value of the entity, e.g. the PID.
* @param {{type: string, values: {name: string, value: any}[]}[]} settings The settings for all renderers.
*/
export const getEntity = async function (
value: string,
settings: {
Expand All @@ -107,6 +134,7 @@ export const getEntity = async function (
}[];
}[],
): Promise<GenericIdentifierType> {
// Try to get the entity from the database
try {
const db = await dbPromise;
const entity:
Expand All @@ -120,39 +148,49 @@ export const getEntity = async function (
| undefined = await db.get('entities', value);

if (entity !== undefined) {
// If the entity was found, check if the TTL has expired
console.debug('Found entity for value in db', entity, value);
const entitySettings = settings.find(value => value.type === entity.rendererKey)?.values;
const ttl = entitySettings?.find(value => value.name === 'ttl');

if (ttl != undefined && ttl.value != undefined && (new Date().getTime() - entity.lastAccess.getTime() > ttl.value || ttl.value === 0)) {
// If the TTL has expired, delete the entity from the database and move on to creating a new one (down below)
console.log('TTL expired! Deleting entry in db', ttl.value, new Date().getTime() - entity.lastAccess.getTime());
await deleteEntity(value);
} else {
// If the TTL has not expired, get a new renderer and return it
console.log('TTL not expired or undefined', new Date().getTime() - entity.lastAccess.getTime());
const renderer = new (renderers.find(renderer => renderer.key === entity.rendererKey).constructor)(value, entitySettings);
// if (renderer.hasCorrectFormat()) {
renderer.settings = entitySettings;
await renderer.init(entity.lastData);
return renderer;
// }
}
}
} catch (error) {
console.error('Could not get entity from db', error);
}

// If no entity was found, create a new one, initialize it and it to the database
console.debug('No valid entity found for value in db', value);
const renderer = await Parser.getBestFit(value, settings);
// renderer.settings = settings.find(value => value.type === renderer.getSettingsKey())?.values
// await renderer.init()
renderer.settings = settings.find(value => value.type === renderer.getSettingsKey())?.values;
await renderer.init();
await addEntity(renderer);
console.debug('added entity to db', value, renderer);
return renderer;
};

/**
* Deletes an entity from the database.
* @param value The value of the entity to delete.
*/
export async function deleteEntity(value: string) {
const db = await dbPromise;

// Delete the entity
await db.delete('entities', value);

// Delete all relations for the entity
const tx = db.transaction('relations', 'readwrite');
const index = tx.store.index('by-start');
let cursor = await index.openCursor();
Expand All @@ -166,13 +204,13 @@ export async function deleteEntity(value: string) {
await tx.done;
}

export async function deleteAllByContext(context: string) {
/**
* Clears all entities from the database.
* @returns {Promise<void>} A promise that resolves when all entities have been deleted.
*/
export async function clearEntities() {
const db = await dbPromise;
const tx = db.transaction('entities', 'readwrite');
const entities = await tx.store.index('by-context').getAll(context);
for (const entity of entities) {
await deleteEntity(entity.value);
}
console.log('deleted all entities for context', context);
await tx.done;
await db.clear('entities');
await db.clear('relations');
console.log('cleared entities');
}

0 comments on commit d97c0f4

Please sign in to comment.