import { Injectable } from '@angular/core'; import Dexie from 'dexie'; import {IMigration, Migration} from './Migration'; import {IMenuItem, MenuItem} from './MenuItem'; import {KeyValue, IKeyValue} from './KeyValue'; import {Codium, ICodium} from './Codium'; import {Database, IDatabase} from './Database'; import {DatabaseColumn, IDatabaseColumn} from './DatabaseColumn'; import {DatabaseEntry, IDatabaseEntry} from './DatabaseEntry'; import {FileGroup, IFileGroup} from './FileGroup'; import {Page, IPage} from './Page'; import {PageNode, IPageNode} from './PageNode'; @Injectable({ providedIn: 'root' }) export class DatabaseService extends Dexie { protected static registeredModels = [ Migration, MenuItem, KeyValue, Codium, Database, DatabaseColumn, DatabaseEntry, FileGroup, Page, PageNode ]; protected initialized = false; migrations!: Dexie.Table; menuItems!: Dexie.Table; keyValues!: Dexie.Table; codiums!: Dexie.Table; databases!: Dexie.Table; databaseColumns!: Dexie.Table; databaseEntries!: Dexie.Table; fileGroups!: Dexie.Table; pages!: Dexie.Table; pageNodes!: Dexie.Table; constructor( ) { super('NodedLocalDatabase'); } public async getKeyValue(key: string): Promise { const matches = await this.keyValues.where({ key }).toArray(); if ( matches.length > 0 ) { return matches[0] as KeyValue; } return new KeyValue(key, '', false); } public async createSchemata() { if ( this.initialized ) { return; } this.initialized = true; console.log('db', this); const staticClass = this.constructor as typeof DatabaseService; const schema: any = {}; for ( const ModelClass of staticClass.registeredModels ) { ModelClass.dbService = this; schema[ModelClass.getTableName()] = ModelClass.getSchema(); } await this.version(15).stores(schema); await this.open(); this.migrations = this.table('migrations'); this.migrations.mapToClass(Migration); this.menuItems = this.table('menuItems'); this.menuItems.mapToClass(MenuItem); this.keyValues = this.table('keyValues'); this.keyValues.mapToClass(KeyValue); this.codiums = this.table('codiums'); this.codiums.mapToClass(Codium); this.databases = this.table('databases'); this.databases.mapToClass(Database); this.databaseColumns = this.table('databaseColumns'); this.databaseColumns.mapToClass(DatabaseColumn); this.databaseEntries = this.table('databaseEntries'); this.databaseEntries.mapToClass(DatabaseEntry); this.fileGroups = this.table('fileGroups'); this.fileGroups.mapToClass(FileGroup); this.pages = this.table('pages'); this.pages.mapToClass(Page); this.pageNodes = this.table('pageNodes'); this.pageNodes.mapToClass(PageNode); } /** Return the local database records that need to be synced up with the server. */ public async getDirtyRecords() { const codiums = await this.codiums.where({ needsServerUpdate: 1 }).toArray() as Codium[]; const databases = await this.databases.where({ needsServerUpdate: 1 }).toArray() as Database[]; const databaseColumns = await this.databaseColumns.where({ needsServerUpdate: 1 }).toArray() as DatabaseColumn[]; const databaseEntries = await this.databaseEntries.where({ needsServerUpdate: 1 }).toArray() as DatabaseEntry[]; const fileGroups = await this.fileGroups.where({ needsServerUpdate: 1 }).toArray() as FileGroup[]; const pages = await this.pages.where({ needsServerUpdate: 1 }).toArray() as Page[]; const pageNodes = await this.pageNodes.where({ needsServerUpdate: 1 }).toArray() as PageNode[]; return { codiums: codiums.map(x => x.getSaveRecord()), databases: databases.map(x => x.getSaveRecord()), databaseColumns: databaseColumns.map(x => x.getSaveRecord()), databaseEntries: databaseEntries.map(x => x.getSaveRecord()), fileGroups: fileGroups.map(x => x.getSaveRecord()), pages: pages.map(x => x.getSaveRecord()), pageNodes: pageNodes.map(x => x.getSaveRecord()), }; } public async purge() { console.warn('Purging all local data!'); await Promise.all([ this.migrations.clear(), this.menuItems.clear(), this.keyValues.clear(), this.codiums.clear(), this.databases.clear(), this.databaseColumns.clear(), this.databaseEntries.clear(), this.fileGroups.clear(), this.pages.clear(), this.pageNodes.clear(), ]); } }