MOBILE-3977 core: Reuse databases initialization
parent
7a2a8c3e98
commit
359d7ab5a5
|
@ -44,6 +44,7 @@ import { CoreLang } from '@services/lang';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { asyncInstance, AsyncInstance } from '../utils/async-instance';
|
import { asyncInstance, AsyncInstance } from '../utils/async-instance';
|
||||||
import { CoreDatabaseTable } from './database/database-table';
|
import { CoreDatabaseTable } from './database/database-table';
|
||||||
|
import { CoreDatabaseCachingStrategy } from './database/database-table-proxy';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QR Code type enumeration.
|
* QR Code type enumeration.
|
||||||
|
@ -140,7 +141,11 @@ export class CoreSite {
|
||||||
) {
|
) {
|
||||||
this.logger = CoreLogger.getInstance('CoreSite');
|
this.logger = CoreLogger.getInstance('CoreSite');
|
||||||
this.siteUrl = CoreUrlUtils.removeUrlParams(this.siteUrl); // Make sure the URL doesn't have params.
|
this.siteUrl = CoreUrlUtils.removeUrlParams(this.siteUrl); // Make sure the URL doesn't have params.
|
||||||
this.cacheTable = asyncInstance(() => CoreSites.getCacheTable(this));
|
this.cacheTable = asyncInstance(() => CoreSites.getSiteTable(CoreSite.WS_CACHE_TABLE, {
|
||||||
|
siteId: this.getId(),
|
||||||
|
database: this.getDb(),
|
||||||
|
config: { cachingStrategy: CoreDatabaseCachingStrategy.None },
|
||||||
|
}));
|
||||||
this.setInfo(infos);
|
this.setInfo(infos);
|
||||||
this.calculateOfflineDisabled();
|
this.calculateOfflineDisabled();
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,10 @@ import {
|
||||||
} from '@services/database/filepool';
|
} from '@services/database/filepool';
|
||||||
import { CoreFileHelper } from './file-helper';
|
import { CoreFileHelper } from './file-helper';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-proxy';
|
||||||
|
import { lazyMap, LazyMap } from '../utils/lazy-map';
|
||||||
|
import { asyncInstance, AsyncInstance } from '../utils/async-instance';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Factory for handling downloading files and retrieve downloaded files.
|
* Factory for handling downloading files and retrieve downloaded files.
|
||||||
|
@ -101,11 +102,20 @@ export class CoreFilepoolProvider {
|
||||||
// Variables for DB.
|
// Variables for DB.
|
||||||
protected appDB: Promise<SQLiteDB>;
|
protected appDB: Promise<SQLiteDB>;
|
||||||
protected resolveAppDB!: (appDB: SQLiteDB) => void;
|
protected resolveAppDB!: (appDB: SQLiteDB) => void;
|
||||||
protected filesTables: Record<string, CorePromisedValue<CoreDatabaseTable<CoreFilepoolFileEntry, 'fileId'>>> = {};
|
protected filesTables: LazyMap<AsyncInstance<CoreDatabaseTable<CoreFilepoolFileEntry, 'fileId'>>>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
|
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
|
||||||
this.logger = CoreLogger.getInstance('CoreFilepoolProvider');
|
this.logger = CoreLogger.getInstance('CoreFilepoolProvider');
|
||||||
|
this.filesTables = lazyMap(
|
||||||
|
siteId => asyncInstance(
|
||||||
|
() => CoreSites.getSiteTable<CoreFilepoolFileEntry, 'fileId'>(FILES_TABLE_NAME, {
|
||||||
|
siteId,
|
||||||
|
config: { cachingStrategy: CoreDatabaseCachingStrategy.Lazy },
|
||||||
|
primaryKeyColumns: ['fileId'],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,11 +138,9 @@ export class CoreFilepoolProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesTable = await this.filesTables[siteId];
|
await this.filesTables[siteId].destroy();
|
||||||
|
|
||||||
delete this.filesTables[siteId];
|
delete this.filesTables[siteId];
|
||||||
|
|
||||||
await filesTable.destroy();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,33 +157,6 @@ export class CoreFilepoolProvider {
|
||||||
this.resolveAppDB(CoreApp.getDB());
|
this.resolveAppDB(CoreApp.getDB());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get files table.
|
|
||||||
*
|
|
||||||
* @param siteId Site id.
|
|
||||||
* @returns Files table.
|
|
||||||
*/
|
|
||||||
async getFilesTable(siteId?: string): Promise<CoreDatabaseTable<CoreFilepoolFileEntry, 'fileId'>> {
|
|
||||||
siteId = siteId ?? CoreSites.getCurrentSiteId();
|
|
||||||
|
|
||||||
if (!(siteId in this.filesTables)) {
|
|
||||||
const filesTable = this.filesTables[siteId] = new CorePromisedValue();
|
|
||||||
const database = await CoreSites.getSiteDb(siteId);
|
|
||||||
const table = new CoreDatabaseTableProxy<CoreFilepoolFileEntry, 'fileId'>(
|
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Lazy },
|
|
||||||
database,
|
|
||||||
FILES_TABLE_NAME,
|
|
||||||
['fileId'],
|
|
||||||
);
|
|
||||||
|
|
||||||
await table.initialize();
|
|
||||||
|
|
||||||
filesTable.resolve(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.filesTables[siteId];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link a file with a component.
|
* Link a file with a component.
|
||||||
*
|
*
|
||||||
|
@ -262,9 +243,7 @@ export class CoreFilepoolProvider {
|
||||||
...data,
|
...data,
|
||||||
};
|
};
|
||||||
|
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
await this.filesTables[siteId].insert(record);
|
||||||
|
|
||||||
await filesTable.insert(record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -605,14 +584,13 @@ export class CoreFilepoolProvider {
|
||||||
*/
|
*/
|
||||||
async clearFilepool(siteId: string): Promise<void> {
|
async clearFilepool(siteId: string): Promise<void> {
|
||||||
const db = await CoreSites.getSiteDb(siteId);
|
const db = await CoreSites.getSiteDb(siteId);
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
|
|
||||||
// Read the data first to be able to notify the deletions.
|
// Read the data first to be able to notify the deletions.
|
||||||
const filesEntries = await filesTable.all();
|
const filesEntries = await this.filesTables[siteId].all();
|
||||||
const filesLinks = await db.getAllRecords<CoreFilepoolLinksRecord>(LINKS_TABLE_NAME);
|
const filesLinks = await db.getAllRecords<CoreFilepoolLinksRecord>(LINKS_TABLE_NAME);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
filesTable.delete(),
|
this.filesTables[siteId].delete(),
|
||||||
db.deleteRecords(LINKS_TABLE_NAME),
|
db.deleteRecords(LINKS_TABLE_NAME),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -1167,14 +1145,13 @@ export class CoreFilepoolProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = await CoreSites.getSiteDb(siteId);
|
const db = await CoreSites.getSiteDb(siteId);
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
const extension = CoreMimetypeUtils.getFileExtension(entry.path);
|
const extension = CoreMimetypeUtils.getFileExtension(entry.path);
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
// Files does not have extension. Invalidate file (stale = true).
|
// Files does not have extension. Invalidate file (stale = true).
|
||||||
// Minor problem: file will remain in the filesystem once downloaded again.
|
// Minor problem: file will remain in the filesystem once downloaded again.
|
||||||
this.logger.debug('Staled file with no extension ' + entry.fileId);
|
this.logger.debug('Staled file with no extension ' + entry.fileId);
|
||||||
|
|
||||||
await filesTable.update({ stale: 1 }, { fileId: entry.fileId });
|
await this.filesTables[siteId].update({ stale: 1 }, { fileId: entry.fileId });
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1184,7 +1161,7 @@ export class CoreFilepoolProvider {
|
||||||
entry.fileId = CoreMimetypeUtils.removeExtension(fileId);
|
entry.fileId = CoreMimetypeUtils.removeExtension(fileId);
|
||||||
entry.extension = extension;
|
entry.extension = extension;
|
||||||
|
|
||||||
await filesTable.update(entry, { fileId });
|
await this.filesTables[siteId].update(entry, { fileId });
|
||||||
if (entry.fileId == fileId) {
|
if (entry.fileId == fileId) {
|
||||||
// File ID hasn't changed, we're done.
|
// File ID hasn't changed, we're done.
|
||||||
this.logger.debug('Removed extesion ' + extension + ' from file ' + entry.fileId);
|
this.logger.debug('Removed extesion ' + extension + ' from file ' + entry.fileId);
|
||||||
|
@ -1445,13 +1422,12 @@ export class CoreFilepoolProvider {
|
||||||
*/
|
*/
|
||||||
async getFilesByComponent(siteId: string, component: string, componentId?: string | number): Promise<CoreFilepoolFileEntry[]> {
|
async getFilesByComponent(siteId: string, component: string, componentId?: string | number): Promise<CoreFilepoolFileEntry[]> {
|
||||||
const db = await CoreSites.getSiteDb(siteId);
|
const db = await CoreSites.getSiteDb(siteId);
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
const items = await this.getComponentFiles(db, component, componentId);
|
const items = await this.getComponentFiles(db, component, componentId);
|
||||||
const files: CoreFilepoolFileEntry[] = [];
|
const files: CoreFilepoolFileEntry[] = [];
|
||||||
|
|
||||||
await Promise.all(items.map(async (item) => {
|
await Promise.all(items.map(async (item) => {
|
||||||
try {
|
try {
|
||||||
const fileEntry = await filesTable.findByPrimaryKey({ fileId: item.fileId });
|
const fileEntry = await this.filesTables[siteId].findByPrimaryKey({ fileId: item.fileId });
|
||||||
|
|
||||||
if (!fileEntry) {
|
if (!fileEntry) {
|
||||||
return;
|
return;
|
||||||
|
@ -2184,9 +2160,7 @@ export class CoreFilepoolProvider {
|
||||||
* @return Resolved with file object from DB on success, rejected otherwise.
|
* @return Resolved with file object from DB on success, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
protected async hasFileInPool(siteId: string, fileId: string): Promise<CoreFilepoolFileEntry> {
|
protected async hasFileInPool(siteId: string, fileId: string): Promise<CoreFilepoolFileEntry> {
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
return this.filesTables[siteId].findByPrimaryKey({ fileId });
|
||||||
|
|
||||||
return filesTable.findByPrimaryKey({ fileId });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2218,17 +2192,15 @@ export class CoreFilepoolProvider {
|
||||||
* @return Resolved on success.
|
* @return Resolved on success.
|
||||||
*/
|
*/
|
||||||
async invalidateAllFiles(siteId: string, onlyUnknown: boolean = true): Promise<void> {
|
async invalidateAllFiles(siteId: string, onlyUnknown: boolean = true): Promise<void> {
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
|
|
||||||
onlyUnknown
|
onlyUnknown
|
||||||
? await filesTable.updateWhere(
|
? await this.filesTables[siteId].updateWhere(
|
||||||
{ stale: 1 },
|
{ stale: 1 },
|
||||||
{
|
{
|
||||||
sql: CoreFilepoolProvider.FILE_IS_UNKNOWN_SQL,
|
sql: CoreFilepoolProvider.FILE_IS_UNKNOWN_SQL,
|
||||||
js: CoreFilepoolProvider.FILE_IS_UNKNOWN_JS,
|
js: CoreFilepoolProvider.FILE_IS_UNKNOWN_JS,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: await filesTable.update({ stale: 1 });
|
: await this.filesTables[siteId].update({ stale: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2247,9 +2219,7 @@ export class CoreFilepoolProvider {
|
||||||
const file = await this.fixPluginfileURL(siteId, fileUrl);
|
const file = await this.fixPluginfileURL(siteId, fileUrl);
|
||||||
const fileId = this.getFileIdByUrl(CoreFileHelper.getFileUrl(file));
|
const fileId = this.getFileIdByUrl(CoreFileHelper.getFileUrl(file));
|
||||||
|
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
await this.filesTables[siteId].update({ stale: 1 }, { fileId });
|
||||||
|
|
||||||
await filesTable.update({ stale: 1 }, { fileId });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2269,7 +2239,6 @@ export class CoreFilepoolProvider {
|
||||||
onlyUnknown: boolean = true,
|
onlyUnknown: boolean = true,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const db = await CoreSites.getSiteDb(siteId);
|
const db = await CoreSites.getSiteDb(siteId);
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
const items = await this.getComponentFiles(db, component, componentId);
|
const items = await this.getComponentFiles(db, component, componentId);
|
||||||
|
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
|
@ -2277,6 +2246,8 @@ export class CoreFilepoolProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
siteId = siteId ?? CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
const fileIds = items.map((item) => item.fileId);
|
const fileIds = items.map((item) => item.fileId);
|
||||||
|
|
||||||
const whereAndParams = db.getInOrEqual(fileIds);
|
const whereAndParams = db.getInOrEqual(fileIds);
|
||||||
|
@ -2287,7 +2258,7 @@ export class CoreFilepoolProvider {
|
||||||
whereAndParams.sql += ' AND (' + CoreFilepoolProvider.FILE_IS_UNKNOWN_SQL + ')';
|
whereAndParams.sql += ' AND (' + CoreFilepoolProvider.FILE_IS_UNKNOWN_SQL + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
await filesTable.updateWhere(
|
await this.filesTables[siteId].updateWhere(
|
||||||
{ stale: 1 },
|
{ stale: 1 },
|
||||||
{
|
{
|
||||||
sql: whereAndParams.sql,
|
sql: whereAndParams.sql,
|
||||||
|
@ -2714,7 +2685,6 @@ export class CoreFilepoolProvider {
|
||||||
*/
|
*/
|
||||||
protected async removeFileById(siteId: string, fileId: string): Promise<void> {
|
protected async removeFileById(siteId: string, fileId: string): Promise<void> {
|
||||||
const db = await CoreSites.getSiteDb(siteId);
|
const db = await CoreSites.getSiteDb(siteId);
|
||||||
const filesTable = await this.getFilesTable(siteId);
|
|
||||||
|
|
||||||
// Get the path to the file first since it relies on the file object stored in the pool.
|
// Get the path to the file first since it relies on the file object stored in the pool.
|
||||||
// Don't use getFilePath to prevent performing 2 DB requests.
|
// Don't use getFilePath to prevent performing 2 DB requests.
|
||||||
|
@ -2741,7 +2711,7 @@ export class CoreFilepoolProvider {
|
||||||
const promises: Promise<unknown>[] = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
|
||||||
// Remove entry from filepool store.
|
// Remove entry from filepool store.
|
||||||
promises.push(filesTable.delete(conditions));
|
promises.push(this.filesTables[siteId].delete(conditions));
|
||||||
|
|
||||||
// Remove links.
|
// Remove links.
|
||||||
promises.push(db.deleteRecords(LINKS_TABLE_NAME, conditions));
|
promises.push(db.deleteRecords(LINKS_TABLE_NAME, conditions));
|
||||||
|
|
|
@ -31,9 +31,8 @@ import {
|
||||||
CoreSiteConfig,
|
CoreSiteConfig,
|
||||||
CoreSitePublicConfigResponse,
|
CoreSitePublicConfigResponse,
|
||||||
CoreSiteInfoResponse,
|
CoreSiteInfoResponse,
|
||||||
CoreSiteWSCacheRecord,
|
|
||||||
} from '@classes/site';
|
} from '@classes/site';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB, SQLiteDBRecordValues, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreError } from '@classes/errors/error';
|
||||||
import { CoreSiteError } from '@classes/errors/siteerror';
|
import { CoreSiteError } from '@classes/errors/siteerror';
|
||||||
import { makeSingleton, Translate, Http } from '@singletons';
|
import { makeSingleton, Translate, Http } from '@singletons';
|
||||||
|
@ -60,7 +59,7 @@ import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
|
||||||
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseConfiguration, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
|
|
||||||
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
||||||
|
|
||||||
|
@ -89,7 +88,7 @@ export class CoreSitesProvider {
|
||||||
// Variables for DB.
|
// Variables for DB.
|
||||||
protected appDB: Promise<SQLiteDB>;
|
protected appDB: Promise<SQLiteDB>;
|
||||||
protected resolveAppDB!: (appDB: SQLiteDB) => void;
|
protected resolveAppDB!: (appDB: SQLiteDB) => void;
|
||||||
protected cacheTables: Record<string, CorePromisedValue<CoreDatabaseTable<CoreSiteWSCacheRecord>>> = {};
|
protected siteTables: Record<string, Record<string, CorePromisedValue<CoreDatabaseTable>>> = {};
|
||||||
|
|
||||||
constructor(@Optional() @Inject(CORE_SITE_SCHEMAS) siteSchemas: CoreSiteSchema[][] = []) {
|
constructor(@Optional() @Inject(CORE_SITE_SCHEMAS) siteSchemas: CoreSiteSchema[][] = []) {
|
||||||
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
|
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
|
||||||
|
@ -109,15 +108,17 @@ export class CoreSitesProvider {
|
||||||
*/
|
*/
|
||||||
initialize(): void {
|
initialize(): void {
|
||||||
CoreEvents.on(CoreEvents.SITE_DELETED, async ({ siteId }) => {
|
CoreEvents.on(CoreEvents.SITE_DELETED, async ({ siteId }) => {
|
||||||
if (!siteId || !(siteId in this.cacheTables)) {
|
if (!siteId || !(siteId in this.siteTables)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheTable = await this.cacheTables[siteId];
|
await Promise.all(
|
||||||
|
Object
|
||||||
|
.values(this.siteTables[siteId])
|
||||||
|
.map(promisedTable => promisedTable.then(table => table.destroy())),
|
||||||
|
);
|
||||||
|
|
||||||
delete this.cacheTables[siteId];
|
delete this.siteTables[siteId];
|
||||||
|
|
||||||
await cacheTable.destroy();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,30 +136,46 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get cache table.
|
* Get site table.
|
||||||
*
|
*
|
||||||
* @param siteId Site id.
|
* @param tableName Site table name.
|
||||||
* @returns cache table.
|
* @param options Options to configure table initialization.
|
||||||
|
* @returns Site table.
|
||||||
*/
|
*/
|
||||||
async getCacheTable(site: CoreSite): Promise<CoreDatabaseTable<CoreSiteWSCacheRecord>> {
|
async getSiteTable<
|
||||||
if (!site.id) {
|
DBRecord extends SQLiteDBRecordValues,
|
||||||
throw new CoreError('Can\'t get cache table for site without id');
|
PrimaryKeyColumn extends keyof DBRecord
|
||||||
|
>(
|
||||||
|
tableName: string,
|
||||||
|
options: Partial<{
|
||||||
|
siteId: string;
|
||||||
|
config: Partial<CoreDatabaseConfiguration>;
|
||||||
|
database: SQLiteDB;
|
||||||
|
primaryKeyColumns: PrimaryKeyColumn[];
|
||||||
|
}> = {},
|
||||||
|
): Promise<CoreDatabaseTable<DBRecord, PrimaryKeyColumn>> {
|
||||||
|
const siteId = options.siteId ?? this.getCurrentSiteId();
|
||||||
|
|
||||||
|
if (!(siteId in this.siteTables)) {
|
||||||
|
this.siteTables[siteId] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(site.id in this.cacheTables)) {
|
if (!(tableName in this.siteTables[siteId])) {
|
||||||
const promisedTable = this.cacheTables[site.id] = new CorePromisedValue();
|
const promisedTable = this.siteTables[siteId][tableName] = new CorePromisedValue();
|
||||||
const table = new CoreDatabaseTableProxy<CoreSiteWSCacheRecord>(
|
const database = options.database ?? await this.getSiteDb(siteId);
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.None },
|
const table = new CoreDatabaseTableProxy<DBRecord, PrimaryKeyColumn>(
|
||||||
site.getDb(),
|
options.config ?? {},
|
||||||
CoreSite.WS_CACHE_TABLE,
|
database,
|
||||||
|
tableName,
|
||||||
|
options.primaryKeyColumns,
|
||||||
);
|
);
|
||||||
|
|
||||||
await table.initialize();
|
await table.initialize();
|
||||||
|
|
||||||
promisedTable.resolve(table);
|
promisedTable.resolve(table as unknown as CoreDatabaseTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.cacheTables[site.id];
|
return this.siteTables[siteId][tableName] as unknown as Promise<CoreDatabaseTable<DBRecord, PrimaryKeyColumn>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy map.
|
||||||
|
*
|
||||||
|
* Lazy maps are empty by default, but entries are generated lazily when accessed.
|
||||||
|
*/
|
||||||
|
export type LazyMap<T> = Record<string, T>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a map that will initialize entries lazily with the given constructor.
|
||||||
|
*
|
||||||
|
* @param lazyConstructor Constructor to use the first time an entry is accessed.
|
||||||
|
* @returns Lazy map.
|
||||||
|
*/
|
||||||
|
export function lazyMap<T>(lazyConstructor: (key: string) => T): LazyMap<T> {
|
||||||
|
const instances = {};
|
||||||
|
|
||||||
|
return new Proxy(instances, {
|
||||||
|
get(target, property, receiver) {
|
||||||
|
if (!(property in instances)) {
|
||||||
|
target[property] = lazyConstructor(property.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Reflect.get(target, property, receiver);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue