MOBILE-3977 config: Add database optimizations
parent
effe53807a
commit
a65919debc
|
@ -12,8 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { SQLiteDB, SQLiteDBRecordValues } from '@classes/sqlitedb';
|
import { SQLiteDB, SQLiteDBRecordValues } from '@classes/sqlitedb';
|
||||||
|
import { CoreConfigProvider } from '@services/config';
|
||||||
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreDatabaseReducer, CoreDatabaseTable, CoreDatabaseConditions, GetDBRecordPrimaryKey } from './database-table';
|
import { CoreDatabaseReducer, CoreDatabaseTable, CoreDatabaseConditions, GetDBRecordPrimaryKey } from './database-table';
|
||||||
import { CoreEagerDatabaseTable } from './eager-database-table';
|
import { CoreEagerDatabaseTable } from './eager-database-table';
|
||||||
import { CoreLazyDatabaseTable } from './lazy-database-table';
|
import { CoreLazyDatabaseTable } from './lazy-database-table';
|
||||||
|
@ -31,6 +34,7 @@ export class CoreDatabaseTableProxy<
|
||||||
|
|
||||||
protected config: CoreDatabaseConfiguration;
|
protected config: CoreDatabaseConfiguration;
|
||||||
protected target: CorePromisedValue<CoreDatabaseTable<DBRecord, PrimaryKeyColumn>> = new CorePromisedValue();
|
protected target: CorePromisedValue<CoreDatabaseTable<DBRecord, PrimaryKeyColumn>> = new CorePromisedValue();
|
||||||
|
protected environmentObserver?: CoreEventObserver;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: Partial<CoreDatabaseConfiguration>,
|
config: Partial<CoreDatabaseConfiguration>,
|
||||||
|
@ -47,11 +51,16 @@ export class CoreDatabaseTableProxy<
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async initialize(): Promise<void> {
|
async initialize(): Promise<void> {
|
||||||
const target = this.createTarget();
|
this.environmentObserver = CoreEvents.on(CoreConfigProvider.ENVIRONMENT_UPDATED, () => this.updateTarget());
|
||||||
|
|
||||||
await target.initialize();
|
await this.updateTarget();
|
||||||
|
}
|
||||||
|
|
||||||
this.target.resolve(target);
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async destroy(): Promise<void> {
|
||||||
|
this.environmentObserver?.off();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,13 +155,46 @@ export class CoreDatabaseTableProxy<
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get database configuration to use at runtime.
|
||||||
|
*
|
||||||
|
* @returns Database configuration.
|
||||||
|
*/
|
||||||
|
protected getRuntimeConfig(): CoreDatabaseConfiguration {
|
||||||
|
return {
|
||||||
|
...this.config,
|
||||||
|
...CoreConstants.CONFIG.databaseOptimizations,
|
||||||
|
...CoreConstants.CONFIG.databaseTableOptimizations?.[this.tableName],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update underlying target instance.
|
||||||
|
*/
|
||||||
|
protected async updateTarget(): Promise<void> {
|
||||||
|
const oldTarget = this.target.value;
|
||||||
|
const newTarget = this.createTarget();
|
||||||
|
|
||||||
|
if (oldTarget) {
|
||||||
|
await oldTarget.destroy();
|
||||||
|
|
||||||
|
this.target.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
await newTarget.initialize();
|
||||||
|
|
||||||
|
this.target.resolve(newTarget);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create proxy target.
|
* Create proxy target.
|
||||||
*
|
*
|
||||||
* @returns Target instance.
|
* @returns Target instance.
|
||||||
*/
|
*/
|
||||||
protected createTarget(): CoreDatabaseTable<DBRecord, PrimaryKeyColumn> {
|
protected createTarget(): CoreDatabaseTable<DBRecord, PrimaryKeyColumn> {
|
||||||
return this.createTable(this.config.cachingStrategy);
|
const config = this.getRuntimeConfig();
|
||||||
|
|
||||||
|
return this.createTable(config.cachingStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -134,6 +134,16 @@ export class CorePromisedValue<T = unknown> implements Promise<T> {
|
||||||
this._reject(reason);
|
this._reject(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset status and value.
|
||||||
|
*/
|
||||||
|
reset(): void {
|
||||||
|
delete this._resolvedValue;
|
||||||
|
delete this._rejectedReason;
|
||||||
|
|
||||||
|
this.initPromise();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the promise and the callbacks.
|
* Initialize the promise and the callbacks.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -145,23 +145,6 @@ export class CoreConstants {
|
||||||
static readonly CONFIG = { ...envJson.config } as unknown as EnvironmentConfig; // Data parsed from config.json files.
|
static readonly CONFIG = { ...envJson.config } as unknown as EnvironmentConfig; // Data parsed from config.json files.
|
||||||
static readonly BUILD = envJson.build as unknown as EnvironmentBuild; // Build info.
|
static readonly BUILD = envJson.build as unknown as EnvironmentBuild; // Build info.
|
||||||
|
|
||||||
/**
|
|
||||||
* Update config with the given values.
|
|
||||||
*
|
|
||||||
* @param config Config updates.
|
|
||||||
*/
|
|
||||||
static patchConfig(config: Partial<EnvironmentConfig>): void {
|
|
||||||
Object.assign(this.CONFIG, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset config values to its original state.
|
|
||||||
*/
|
|
||||||
static resetConfig(): void {
|
|
||||||
Object.keys(this.CONFIG).forEach(key => delete this.CONFIG[key]);
|
|
||||||
Object.assign(this.CONFIG, envJson.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EnvironmentBuild {
|
interface EnvironmentBuild {
|
||||||
|
|
|
@ -12,14 +12,30 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { EnvironmentConfig } from '@/types/config';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { APP_SCHEMA, ConfigDBEntry, CONFIG_TABLE_NAME } from '@services/database/config';
|
import { APP_SCHEMA, ConfigDBEntry, CONFIG_TABLE_NAME } from '@services/database/config';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreConstants } from '../constants';
|
||||||
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
|
|
||||||
|
declare module '@singletons/events' {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Augment CoreEventsData interface with events specific to this service.
|
||||||
|
*
|
||||||
|
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
|
||||||
|
*/
|
||||||
|
export interface CoreEventsData {
|
||||||
|
[CoreConfigProvider.ENVIRONMENT_UPDATED]: EnvironmentConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory to provide access to dynamic and permanent config and settings.
|
* Factory to provide access to dynamic and permanent config and settings.
|
||||||
* It should not be abused into a temporary storage.
|
* It should not be abused into a temporary storage.
|
||||||
|
@ -27,7 +43,10 @@ import { CorePromisedValue } from '@classes/promised-value';
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CoreConfigProvider {
|
export class CoreConfigProvider {
|
||||||
|
|
||||||
|
static readonly ENVIRONMENT_UPDATED = 'environment_updated';
|
||||||
|
|
||||||
protected table: CorePromisedValue<CoreDatabaseTable<ConfigDBEntry, 'name'>> = new CorePromisedValue();
|
protected table: CorePromisedValue<CoreDatabaseTable<ConfigDBEntry, 'name'>> = new CorePromisedValue();
|
||||||
|
protected defaultEnvironment?: EnvironmentConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
|
@ -98,6 +117,33 @@ export class CoreConfigProvider {
|
||||||
await table.insert({ name, value });
|
await table.insert({ name, value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update config with the given values.
|
||||||
|
*
|
||||||
|
* @param config Config updates.
|
||||||
|
*/
|
||||||
|
patchEnvironment(config: Partial<EnvironmentConfig>): void {
|
||||||
|
this.defaultEnvironment = this.defaultEnvironment ?? CoreConstants.CONFIG;
|
||||||
|
|
||||||
|
Object.assign(CoreConstants.CONFIG, config);
|
||||||
|
CoreEvents.trigger(CoreConfigProvider.ENVIRONMENT_UPDATED, CoreConstants.CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset config values to its original state.
|
||||||
|
*/
|
||||||
|
resetEnvironment(): void {
|
||||||
|
if (!this.defaultEnvironment) {
|
||||||
|
// The environment config hasn't been modified; there's not need to reset.
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(CoreConstants.CONFIG).forEach(key => delete CoreConstants.CONFIG[key]);
|
||||||
|
Object.assign(CoreConstants.CONFIG, this.defaultEnvironment);
|
||||||
|
CoreEvents.trigger(CoreConfigProvider.ENVIRONMENT_UPDATED, CoreConstants.CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CoreConfig = makeSingleton(CoreConfigProvider);
|
export const CoreConfig = makeSingleton(CoreConfigProvider);
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { CoreMainMenuLocalizedCustomItem } from '@features/mainmenu/services/mai
|
||||||
import { CoreSitesDemoSiteData } from '@services/sites';
|
import { CoreSitesDemoSiteData } from '@services/sites';
|
||||||
import { OpenFileAction } from '@services/utils/utils';
|
import { OpenFileAction } from '@services/utils/utils';
|
||||||
import { CoreLoginSiteSelectorListMethod } from '@features/login/services/login-helper';
|
import { CoreLoginSiteSelectorListMethod } from '@features/login/services/login-helper';
|
||||||
|
import { CoreDatabaseConfiguration } from '@classes/database/database-table-proxy';
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ export interface EnvironmentConfig {
|
||||||
cache_update_frequency_rarely: number;
|
cache_update_frequency_rarely: number;
|
||||||
default_lang: string;
|
default_lang: string;
|
||||||
languages: Record<string, string>;
|
languages: Record<string, string>;
|
||||||
|
databaseOptimizations?: Partial<CoreDatabaseConfiguration>;
|
||||||
|
databaseTableOptimizations?: Record<string, Partial<CoreDatabaseConfiguration>>;
|
||||||
wsservice: string;
|
wsservice: string;
|
||||||
demo_sites: Record<string, CoreSitesDemoSiteData>;
|
demo_sites: Record<string, CoreSitesDemoSiteData>;
|
||||||
zoomlevels: Record<CoreZoomLevel, number>;
|
zoomlevels: Record<CoreZoomLevel, number>;
|
||||||
|
|
Loading…
Reference in New Issue