MOBILE-3320 core: Refactor database inits

main
Noel De Martin 2020-12-01 18:37:24 +01:00
parent f1bc354be6
commit 17dbc340e0
21 changed files with 282 additions and 173 deletions

View File

@ -18,10 +18,7 @@ import { ApplicationInitStatus, Injector, NgModule } from '@angular/core';
import { CoreApplicationInitStatus } from './classes/application-init-status'; import { CoreApplicationInitStatus } from './classes/application-init-status';
import { CoreFeaturesModule } from './features/features.module'; import { CoreFeaturesModule } from './features/features.module';
import { CoreInterceptor } from './classes/interceptor'; import { CoreInterceptor } from './classes/interceptor';
import { CORE_SITE_SCHEMAS } from './services/sites'; import { getDatabaseProviders } from './services/database';
import { SITE_SCHEMA as FILEPOOL_SITE_SCHEMA } from './services/db/filepool';
import { SITE_SCHEMA as SITES_SITE_SCHEMA } from './services/db/sites';
import { SITE_SCHEMA as SYNC_SITE_SCHEMA } from './services/db/sync';
import { getInitializerProviders } from './initializers'; import { getInitializerProviders } from './initializers';
@NgModule({ @NgModule({
@ -31,15 +28,7 @@ import { getInitializerProviders } from './initializers';
providers: [ providers: [
{ provide: HTTP_INTERCEPTORS, useClass: CoreInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: CoreInterceptor, multi: true },
{ provide: ApplicationInitStatus, useClass: CoreApplicationInitStatus, deps: [Injector] }, { provide: ApplicationInitStatus, useClass: CoreApplicationInitStatus, deps: [Injector] },
{ ...getDatabaseProviders(),
provide: CORE_SITE_SCHEMAS,
useValue: [
FILEPOOL_SITE_SCHEMA,
SITES_SITE_SCHEMA,
SYNC_SITE_SCHEMA,
],
multi: true,
},
...getInitializerProviders(), ...getInitializerProviders(),
], ],
}) })

View File

@ -16,7 +16,7 @@ import { NgModule } from '@angular/core';
import { CORE_SITE_SCHEMAS } from '@services/sites'; import { CORE_SITE_SCHEMAS } from '@services/sites';
import { SITE_SCHEMA, OFFLINE_SITE_SCHEMA } from './services/db/course'; import { SITE_SCHEMA, OFFLINE_SITE_SCHEMA } from './services/database/course';
@NgModule({ @NgModule({
providers: [ providers: [

View File

@ -15,7 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreCourseManualCompletionDBRecord, MANUAL_COMPLETION_TABLE } from './db/course'; import { CoreCourseManualCompletionDBRecord, MANUAL_COMPLETION_TABLE } from './database/course';
import { CoreStatusWithWarningsWSResponse } from '@services/ws'; import { CoreStatusWithWarningsWSResponse } from '@services/ws';
/** /**

View File

@ -26,7 +26,7 @@ import { CoreConstants } from '@/core/constants';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile } from '@services/ws'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile } from '@services/ws';
import { CoreCourseStatusDBRecord, COURSE_STATUS_TABLE } from './db/course'; import { CoreCourseStatusDBRecord, COURSE_STATUS_TABLE } from './database/course';
import { CoreCourseOffline } from './course-offline'; import { CoreCourseOffline } from './course-offline';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { import {

View File

@ -0,0 +1,31 @@
// (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.
import { CoreApp } from '@services/app';
import { CoreConfig } from '@services/config';
import { CoreCron } from '@services/cron';
import { CoreFilepool } from '@services/filepool';
import { CoreLocalNotifications } from '@services/local-notifications';
import { CoreSites } from '@services/sites';
export default async function(): Promise<void> {
await Promise.all([
CoreApp.instance.initialiseDatabase(),
CoreConfig.instance.initialiseDatabase(),
CoreCron.instance.initialiseDatabase(),
CoreFilepool.instance.initialiseDatabase(),
CoreLocalNotifications.instance.initialiseDatabase(),
CoreSites.instance.initialiseDatabase(),
]);
}

View File

@ -25,7 +25,15 @@ import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
import { makeSingleton, Keyboard, Network, StatusBar, Platform, Device } from '@singletons'; import { makeSingleton, Keyboard, Network, StatusBar, Platform, Device } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreColors } from '@singletons/colors'; import { CoreColors } from '@singletons/colors';
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/db/app'; import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/database/app';
/**
* Object responsible of managing schema versions.
*/
type SchemaVersionsManager = {
get(schemaName: string): Promise<number>;
set(schemaName: string, version: number): Promise<void>;
};
/** /**
* Factory to provide some global functionalities, like access to the global app database. * Factory to provide some global functionalities, like access to the global app database.
@ -55,14 +63,13 @@ export class CoreAppProvider {
protected forceOffline = false; protected forceOffline = false;
// Variables for DB. // Variables for DB.
protected createVersionsTableReady: Promise<void>; protected schemaVersionsManager: Promise<SchemaVersionsManager>;
protected resolveSchemaVersionsManager!: (schemaVersionsManager: SchemaVersionsManager) => void;
constructor(protected router: Router) { constructor(protected router: Router) {
this.logger = CoreLogger.getInstance('CoreAppProvider'); this.schemaVersionsManager = new Promise(resolve => this.resolveSchemaVersionsManager = resolve);
this.db = CoreDB.instance.getDB(DBNAME); this.db = CoreDB.instance.getDB(DBNAME);
this.logger = CoreLogger.getInstance('CoreAppProvider');
// Create the schema versions table.
this.createVersionsTableReady = this.db.createTableFromSchema(SCHEMA_VERSIONS_TABLE_SCHEMA);
// @todo // @todo
// this.platform.registerBackButtonAction(() => { // this.platform.registerBackButtonAction(() => {
@ -79,6 +86,30 @@ export class CoreAppProvider {
return !!navigator.webdriver; return !!navigator.webdriver;
} }
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
await this.db.createTableFromSchema(SCHEMA_VERSIONS_TABLE_SCHEMA);
this.resolveSchemaVersionsManager({
get: async name => {
try {
// Fetch installed version of the schema.
const entry = await this.db.getRecord<SchemaVersionsDBEntry>(SCHEMA_VERSIONS_TABLE_NAME, { name });
return entry.version;
} catch (error) {
// No installed version yet.
return 0;
}
},
set: async (name, version) => {
await this.db.insertRecord(SCHEMA_VERSIONS_TABLE_NAME, { name, version });
},
});
}
/** /**
* Check if the browser supports mediaDevices.getUserMedia. * Check if the browser supports mediaDevices.getUserMedia.
* *
@ -115,20 +146,8 @@ export class CoreAppProvider {
async createTablesFromSchema(schema: CoreAppSchema): Promise<void> { async createTablesFromSchema(schema: CoreAppSchema): Promise<void> {
this.logger.debug(`Apply schema to app DB: ${schema.name}`); this.logger.debug(`Apply schema to app DB: ${schema.name}`);
let oldVersion: number; const schemaVersionsManager = await this.schemaVersionsManager;
const oldVersion = await schemaVersionsManager.get(schema.name);
try {
// Wait for the schema versions table to be created.
await this.createVersionsTableReady;
// Fetch installed version of the schema.
const entry = await this.db.getRecord<SchemaVersionsDBEntry>(SCHEMA_VERSIONS_TABLE_NAME, { name: schema.name });
oldVersion = entry.version;
} catch (error) {
// No installed version yet.
oldVersion = 0;
}
if (oldVersion >= schema.version) { if (oldVersion >= schema.version) {
// Version already installed, nothing else to do. // Version already installed, nothing else to do.
@ -145,7 +164,7 @@ export class CoreAppProvider {
} }
// Set installed version. // Set installed version.
await this.db.insertRecord(SCHEMA_VERSIONS_TABLE_NAME, { name: schema.name, version: schema.version }); schemaVersionsManager.set(schema.name, schema.version);
} }
/** /**

View File

@ -17,7 +17,7 @@ import { Injectable } from '@angular/core';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { SQLiteDB } from '@classes/sqlitedb'; import { SQLiteDB } from '@classes/sqlitedb';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CONFIG_TABLE_NAME, APP_SCHEMA, ConfigDBEntry } from '@services/db/config'; import { CONFIG_TABLE_NAME, APP_SCHEMA, ConfigDBEntry } from '@services/database/config';
/** /**
* Factory to provide access to dynamic and permanent config and settings. * Factory to provide access to dynamic and permanent config and settings.
@ -26,14 +26,24 @@ import { CONFIG_TABLE_NAME, APP_SCHEMA, ConfigDBEntry } from '@services/db/confi
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CoreConfigProvider { export class CoreConfigProvider {
protected appDB: SQLiteDB; protected appDB: Promise<SQLiteDB>;
protected dbReady: Promise<void>; // Promise resolved when the app DB is initialized. protected resolveAppDB!: (appDB: SQLiteDB) => void;
constructor() { constructor() {
this.appDB = CoreApp.instance.getDB(); this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
this.dbReady = CoreApp.instance.createTablesFromSchema(APP_SCHEMA).catch(() => { }
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
try {
await CoreApp.instance.createTablesFromSchema(APP_SCHEMA);
} catch (e) {
// Ignore errors. // Ignore errors.
}); }
this.resolveAppDB(CoreApp.instance.getDB());
} }
/** /**
@ -43,9 +53,9 @@ export class CoreConfigProvider {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async delete(name: string): Promise<void> { async delete(name: string): Promise<void> {
await this.dbReady; const db = await this.appDB;
await this.appDB.deleteRecords(CONFIG_TABLE_NAME, { name }); await db.deleteRecords(CONFIG_TABLE_NAME, { name });
} }
/** /**
@ -56,10 +66,10 @@ export class CoreConfigProvider {
* @return Resolves upon success along with the config data. Reject on failure. * @return Resolves upon success along with the config data. Reject on failure.
*/ */
async get<T>(name: string, defaultValue?: T): Promise<T> { async get<T>(name: string, defaultValue?: T): Promise<T> {
await this.dbReady; const db = await this.appDB;
try { try {
const entry = await this.appDB.getRecord<ConfigDBEntry>(CONFIG_TABLE_NAME, { name }); const entry = await db.getRecord<ConfigDBEntry>(CONFIG_TABLE_NAME, { name });
return entry.value; return entry.value;
} catch (error) { } catch (error) {
@ -79,9 +89,9 @@ export class CoreConfigProvider {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async set(name: string, value: number | string): Promise<void> { async set(name: string, value: number | string): Promise<void> {
await this.dbReady; const db = await this.appDB;
await this.appDB.insertRecord(CONFIG_TABLE_NAME, { name, value }); await db.insertRecord(CONFIG_TABLE_NAME, { name, value });
} }
} }

View File

@ -23,7 +23,7 @@ import { CoreError } from '@classes/errors/error';
import { makeSingleton, Network } from '@singletons'; import { makeSingleton, Network } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { APP_SCHEMA, CRON_TABLE_NAME, CronDBEntry } from '@services/db/cron'; import { APP_SCHEMA, CRON_TABLE_NAME, CronDBEntry } from '@services/database/cron';
/* /*
* Service to handle cron processes. The registered processes will be executed every certain time. * Service to handle cron processes. The registered processes will be executed every certain time.
@ -37,18 +37,16 @@ export class CoreCronDelegate {
static readonly MAX_TIME_PROCESS = 120000; // Max time a process can block the queue. Defaults to 2 minutes. static readonly MAX_TIME_PROCESS = 120000; // Max time a process can block the queue. Defaults to 2 minutes.
protected logger: CoreLogger; protected logger: CoreLogger;
protected appDB: SQLiteDB;
protected dbReady: Promise<void>; // Promise resolved when the app DB is initialized.
protected handlers: { [s: string]: CoreCronHandler } = {}; protected handlers: { [s: string]: CoreCronHandler } = {};
protected queuePromise: Promise<void> = Promise.resolve(); protected queuePromise: Promise<void> = Promise.resolve();
constructor(zone: NgZone) { // Variables for DB.
this.logger = CoreLogger.getInstance('CoreCronDelegate'); protected appDB: Promise<SQLiteDB>;
protected resolveAppDB!: (appDB: SQLiteDB) => void;
this.appDB = CoreApp.instance.getDB(); constructor(zone: NgZone) {
this.dbReady = CoreApp.instance.createTablesFromSchema(APP_SCHEMA).catch(() => { this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
// Ignore errors. this.logger = CoreLogger.getInstance('CoreCronDelegate');
});
// When the app is re-connected, start network handlers that were stopped. // When the app is re-connected, start network handlers that were stopped.
Network.instance.onConnect().subscribe(() => { Network.instance.onConnect().subscribe(() => {
@ -59,6 +57,19 @@ export class CoreCronDelegate {
}); });
} }
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
try {
await CoreApp.instance.createTablesFromSchema(APP_SCHEMA);
} catch (e) {
// Ignore errors.
}
this.resolveAppDB(CoreApp.instance.getDB());
}
/** /**
* Try to execute a handler. It will schedule the next execution once done. * Try to execute a handler. It will schedule the next execution once done.
* If the handler cannot be executed or it fails, it will be re-executed after mmCoreCronMinInterval. * If the handler cannot be executed or it fails, it will be re-executed after mmCoreCronMinInterval.
@ -235,12 +246,11 @@ export class CoreCronDelegate {
* @return Promise resolved with the handler's last execution time. * @return Promise resolved with the handler's last execution time.
*/ */
protected async getHandlerLastExecutionTime(name: string): Promise<number> { protected async getHandlerLastExecutionTime(name: string): Promise<number> {
await this.dbReady; const db = await this.appDB;
const id = this.getHandlerLastExecutionId(name); const id = this.getHandlerLastExecutionId(name);
try { try {
const entry = await this.appDB.getRecord<CronDBEntry>(CRON_TABLE_NAME, { id }); const entry = await db.getRecord<CronDBEntry>(CRON_TABLE_NAME, { id });
const time = Number(entry.value); const time = Number(entry.value);
@ -395,15 +405,14 @@ export class CoreCronDelegate {
* @return Promise resolved when the execution time is saved. * @return Promise resolved when the execution time is saved.
*/ */
protected async setHandlerLastExecutionTime(name: string, time: number): Promise<void> { protected async setHandlerLastExecutionTime(name: string, time: number): Promise<void> {
await this.dbReady; const db = await this.appDB;
const id = this.getHandlerLastExecutionId(name); const id = this.getHandlerLastExecutionId(name);
const entry = { const entry = {
id, id,
value: time, value: time,
}; };
await this.appDB.insertRecord(CRON_TABLE_NAME, entry); await db.insertRecord(CRON_TABLE_NAME, entry);
} }
/** /**

View File

@ -0,0 +1,32 @@
// (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.
import { Provider } from '@angular/core';
import { CORE_SITE_SCHEMAS } from '@services/sites';
import { SITE_SCHEMA as FILEPOOL_SITE_SCHEMA } from './filepool';
import { SITE_SCHEMA as SITES_SITE_SCHEMA } from './sites';
import { SITE_SCHEMA as SYNC_SITE_SCHEMA } from './sync';
export function getDatabaseProviders(): Provider[] {
return [{
provide: CORE_SITE_SCHEMAS,
useValue: [
FILEPOOL_SITE_SCHEMA,
SITES_SITE_SCHEMA,
SYNC_SITE_SCHEMA,
],
multi: true,
}];
}

View File

@ -45,7 +45,7 @@ import {
CoreFilepoolPackageEntry, CoreFilepoolPackageEntry,
CoreFilepoolQueueEntry, CoreFilepoolQueueEntry,
CoreFilepoolQueueDBEntry, CoreFilepoolQueueDBEntry,
} from '@services/db/filepool'; } from '@services/database/filepool';
/* /*
* Factory for handling downloading files and retrieve downloaded files. * Factory for handling downloading files and retrieve downloaded files.
@ -74,8 +74,6 @@ export class CoreFilepoolProvider {
'isexternalfile = 1 OR ((revision IS NULL OR revision = 0) AND (timemodified IS NULL OR timemodified = 0))'; 'isexternalfile = 1 OR ((revision IS NULL OR revision = 0) AND (timemodified IS NULL OR timemodified = 0))';
protected logger: CoreLogger; protected logger: CoreLogger;
protected appDB: SQLiteDB;
protected dbReady: Promise<void>; // Promise resolved when the app DB is initialized.
protected queueState = CoreFilepoolProvider.QUEUE_PAUSED; protected queueState = CoreFilepoolProvider.QUEUE_PAUSED;
protected urlAttributes: RegExp[] = [ protected urlAttributes: RegExp[] = [
new RegExp('(\\?|&)token=([A-Za-z0-9]*)'), new RegExp('(\\?|&)token=([A-Za-z0-9]*)'),
@ -91,17 +89,30 @@ export class CoreFilepoolProvider {
protected packagesPromises: { [s: string]: { [s: string]: Promise<void> } } = {}; protected packagesPromises: { [s: string]: { [s: string]: Promise<void> } } = {};
protected filePromises: { [s: string]: { [s: string]: Promise<string> } } = {}; protected filePromises: { [s: string]: { [s: string]: Promise<string> } } = {};
// Variables for DB.
protected appDB: Promise<SQLiteDB>;
protected resolveAppDB!: (appDB: SQLiteDB) => void;
constructor() { constructor() {
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
this.logger = CoreLogger.getInstance('CoreFilepoolProvider'); this.logger = CoreLogger.getInstance('CoreFilepoolProvider');
this.appDB = CoreApp.instance.getDB();
this.dbReady = CoreApp.instance.createTablesFromSchema(APP_SCHEMA).catch(() => {
// Ignore errors.
});
this.init(); this.init();
} }
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
try {
await CoreApp.instance.createTablesFromSchema(APP_SCHEMA);
} catch (e) {
// Ignore errors.
}
this.resolveAppDB(CoreApp.instance.getDB());
}
/** /**
* Init some properties. * Init some properties.
*/ */
@ -264,11 +275,11 @@ export class CoreFilepoolProvider {
options: CoreFilepoolFileOptions = {}, options: CoreFilepoolFileOptions = {},
link?: CoreFilepoolComponentLink, link?: CoreFilepoolComponentLink,
): Promise<void> { ): Promise<void> {
await this.dbReady;
this.logger.debug(`Adding ${fileId} to the queue`); this.logger.debug(`Adding ${fileId} to the queue`);
await this.appDB.insertRecord(QUEUE_TABLE_NAME, { const db = await this.appDB;
await db.insertRecord(QUEUE_TABLE_NAME, {
siteId, siteId,
fileId, fileId,
url, url,
@ -318,8 +329,6 @@ export class CoreFilepoolProvider {
revision?: number, revision?: number,
alreadyFixed?: boolean, alreadyFixed?: boolean,
): Promise<void> { ): Promise<void> {
await this.dbReady;
if (!CoreFile.instance.isAvailable()) { if (!CoreFile.instance.isAvailable()) {
throw new CoreError('File system cannot be used.'); throw new CoreError('File system cannot be used.');
} }
@ -398,7 +407,9 @@ export class CoreFilepoolProvider {
// Update only when required. // Update only when required.
this.logger.debug(`Updating file ${fileId} which is already in queue`); this.logger.debug(`Updating file ${fileId} which is already in queue`);
return this.appDB.updateRecords(QUEUE_TABLE_NAME, newData, primaryKey).then(() => const db = await this.appDB;
return db.updateRecords(QUEUE_TABLE_NAME, newData, primaryKey).then(() =>
this.getQueuePromise(siteId, fileId, true, onProgress)); this.getQueuePromise(siteId, fileId, true, onProgress));
} }
@ -2110,9 +2121,8 @@ 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 hasFileInQueue(siteId: string, fileId: string): Promise<CoreFilepoolQueueEntry> { protected async hasFileInQueue(siteId: string, fileId: string): Promise<CoreFilepoolQueueEntry> {
await this.dbReady; const db = await this.appDB;
const entry = await db.getRecord<CoreFilepoolQueueEntry>(QUEUE_TABLE_NAME, { siteId, fileId });
const entry = await this.appDB.getRecord<CoreFilepoolQueueEntry>(QUEUE_TABLE_NAME, { siteId, fileId });
if (typeof entry === 'undefined') { if (typeof entry === 'undefined') {
throw new CoreError('File not found in queue.'); throw new CoreError('File not found in queue.');
@ -2444,12 +2454,11 @@ export class CoreFilepoolProvider {
* @return Resolved on success. Rejected on failure. * @return Resolved on success. Rejected on failure.
*/ */
protected async processImportantQueueItem(): Promise<void> { protected async processImportantQueueItem(): Promise<void> {
await this.dbReady;
let items: CoreFilepoolQueueEntry[]; let items: CoreFilepoolQueueEntry[];
const db = await this.appDB;
try { try {
items = await this.appDB.getRecords<CoreFilepoolQueueEntry>( items = await db.getRecords<CoreFilepoolQueueEntry>(
QUEUE_TABLE_NAME, QUEUE_TABLE_NAME,
undefined, undefined,
'priority DESC, added ASC', 'priority DESC, added ASC',
@ -2593,9 +2602,9 @@ export class CoreFilepoolProvider {
* @return Resolved on success. Rejected on failure. It is advised to silently ignore failures. * @return Resolved on success. Rejected on failure. It is advised to silently ignore failures.
*/ */
protected async removeFromQueue(siteId: string, fileId: string): Promise<void> { protected async removeFromQueue(siteId: string, fileId: string): Promise<void> {
await this.dbReady; const db = await this.appDB;
await this.appDB.deleteRecords(QUEUE_TABLE_NAME, { siteId, fileId }); await db.deleteRecords(QUEUE_TABLE_NAME, { siteId, fileId });
} }
/** /**

View File

@ -34,7 +34,7 @@ import {
COMPONENTS_TABLE_NAME, COMPONENTS_TABLE_NAME,
SITES_TABLE_NAME, SITES_TABLE_NAME,
CodeRequestsQueueItem, CodeRequestsQueueItem,
} from '@services/db/local-notifications'; } from '@services/database/local-notifications';
/** /**
* Service to handle local notifications. * Service to handle local notifications.
@ -43,8 +43,6 @@ import {
export class CoreLocalNotificationsProvider { export class CoreLocalNotificationsProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected appDB: SQLiteDB;
protected dbReady: Promise<void>; // Promise resolved when the app DB is initialized.
protected codes: { [s: string]: number } = {}; protected codes: { [s: string]: number } = {};
protected codeRequestsQueue: {[key: string]: CodeRequestsQueueItem} = {}; protected codeRequestsQueue: {[key: string]: CodeRequestsQueueItem} = {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -58,17 +56,31 @@ export class CoreLocalNotificationsProvider {
protected updateSubscription?: Subscription; protected updateSubscription?: Subscription;
protected queueRunner: CoreQueueRunner; // Queue to decrease the number of concurrent calls to the plugin (see MOBILE-3477). protected queueRunner: CoreQueueRunner; // Queue to decrease the number of concurrent calls to the plugin (see MOBILE-3477).
// Variables for DB.
protected appDB: Promise<SQLiteDB>;
protected resolveAppDB!: (appDB: SQLiteDB) => void;
constructor() { constructor() {
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
this.logger = CoreLogger.getInstance('CoreLocalNotificationsProvider'); this.logger = CoreLogger.getInstance('CoreLocalNotificationsProvider');
this.queueRunner = new CoreQueueRunner(10); this.queueRunner = new CoreQueueRunner(10);
this.appDB = CoreApp.instance.getDB();
this.dbReady = CoreApp.instance.createTablesFromSchema(APP_SCHEMA).catch(() => {
// Ignore errors.
});
this.init(); this.init();
} }
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
try {
await CoreApp.instance.createTablesFromSchema(APP_SCHEMA);
} catch (e) {
// Ignore errors.
}
this.resolveAppDB(CoreApp.instance.getDB());
}
/** /**
* Init some properties. * Init some properties.
*/ */
@ -212,8 +224,6 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved when the code is retrieved. * @return Promise resolved when the code is retrieved.
*/ */
protected async getCode(table: string, id: string): Promise<number> { protected async getCode(table: string, id: string): Promise<number> {
await this.dbReady;
const key = table + '#' + id; const key = table + '#' + id;
// Check if the code is already in memory. // Check if the code is already in memory.
@ -221,23 +231,25 @@ export class CoreLocalNotificationsProvider {
return this.codes[key]; return this.codes[key];
} }
const db = await this.appDB;
try { try {
// Check if we already have a code stored for that ID. // Check if we already have a code stored for that ID.
const entry = await this.appDB.getRecord<{id: string; code: number}>(table, { id: id }); const entry = await db.getRecord<{id: string; code: number}>(table, { id: id });
this.codes[key] = entry.code; this.codes[key] = entry.code;
return entry.code; return entry.code;
} catch (err) { } catch (err) {
// No code stored for that ID. Create a new code for it. // No code stored for that ID. Create a new code for it.
const entries = await this.appDB.getRecords<{id: string; code: number}>(table, undefined, 'code DESC'); const entries = await db.getRecords<{id: string; code: number}>(table, undefined, 'code DESC');
let newCode = 0; let newCode = 0;
if (entries.length > 0) { if (entries.length > 0) {
newCode = entries[0].code + 1; newCode = entries[0].code + 1;
} }
await this.appDB.insertRecord(table, { id: id, code: newCode }); await db.insertRecord(table, { id: id, code: newCode });
this.codes[key] = newCode; this.codes[key] = newCode;
return newCode; return newCode;
@ -324,10 +336,10 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved with a boolean indicating if promise is triggered (true) or not. * @return Promise resolved with a boolean indicating if promise is triggered (true) or not.
*/ */
async isTriggered(notification: ILocalNotification, useQueue: boolean = true): Promise<boolean> { async isTriggered(notification: ILocalNotification, useQueue: boolean = true): Promise<boolean> {
await this.dbReady; const db = await this.appDB;
try { try {
const stored = await this.appDB.getRecord<{ id: number; at: number }>( const stored = await db.getRecord<{ id: number; at: number }>(
TRIGGERED_TABLE_NAME, TRIGGERED_TABLE_NAME,
{ id: notification.id }, { id: notification.id },
); );
@ -481,9 +493,9 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved when it is removed. * @return Promise resolved when it is removed.
*/ */
async removeTriggered(id: number): Promise<void> { async removeTriggered(id: number): Promise<void> {
await this.dbReady; const db = await this.appDB;
await this.appDB.deleteRecords(TRIGGERED_TABLE_NAME, { id: id }); await db.deleteRecords(TRIGGERED_TABLE_NAME, { id: id });
} }
/** /**
@ -639,14 +651,13 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved when stored, rejected otherwise. * @return Promise resolved when stored, rejected otherwise.
*/ */
async trigger(notification: ILocalNotification): Promise<number> { async trigger(notification: ILocalNotification): Promise<number> {
await this.dbReady; const db = await this.appDB;
const entry = { const entry = {
id: notification.id, id: notification.id,
at: notification.trigger && notification.trigger.at ? notification.trigger.at.getTime() : Date.now(), at: notification.trigger && notification.trigger.at ? notification.trigger.at.getTime() : Date.now(),
}; };
return this.appDB.insertRecord(TRIGGERED_TABLE_NAME, entry); return db.insertRecord(TRIGGERED_TABLE_NAME, entry);
} }
/** /**
@ -657,12 +668,12 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async updateComponentName(oldName: string, newName: string): Promise<void> { async updateComponentName(oldName: string, newName: string): Promise<void> {
await this.dbReady; const db = await this.appDB;
const oldId = COMPONENTS_TABLE_NAME + '#' + oldName; const oldId = COMPONENTS_TABLE_NAME + '#' + oldName;
const newId = COMPONENTS_TABLE_NAME + '#' + newName; const newId = COMPONENTS_TABLE_NAME + '#' + newName;
await this.appDB.updateRecords(COMPONENTS_TABLE_NAME, { id: newId }, { id: oldId }); await db.updateRecords(COMPONENTS_TABLE_NAME, { id: newId }, { id: oldId });
} }
} }

View File

@ -47,7 +47,7 @@ import {
SiteDBEntry, SiteDBEntry,
CurrentSiteDBEntry, CurrentSiteDBEntry,
SchemaVersionsDBEntry, SchemaVersionsDBEntry,
} from '@services/db/sites'; } from '@services/database/sites';
import { CoreArray } from '../singletons/array'; import { CoreArray } from '../singletons/array';
export const CORE_SITE_SCHEMAS = new InjectionToken('CORE_SITE_SCHEMAS'); export const CORE_SITE_SCHEMAS = new InjectionToken('CORE_SITE_SCHEMAS');
@ -61,25 +61,27 @@ export const CORE_SITE_SCHEMAS = new InjectionToken('CORE_SITE_SCHEMAS');
export class CoreSitesProvider { export class CoreSitesProvider {
// Constants to validate a site version. // Constants to validate a site version.
protected readonly WORKPLACE_APP = 3; protected static readonly WORKPLACE_APP = 3;
protected readonly MOODLE_APP = 2; protected static readonly MOODLE_APP = 2;
protected readonly VALID_VERSION = 1; protected static readonly VALID_VERSION = 1;
protected readonly INVALID_VERSION = -1; protected static readonly INVALID_VERSION = -1;
protected isWPApp = false; protected isWPApp = false;
protected logger: CoreLogger; protected logger: CoreLogger;
protected services = {}; protected services = {};
protected sessionRestored = false; protected sessionRestored = false;
protected currentSite?: CoreSite; protected currentSite?: CoreSite;
protected sites: { [s: string]: CoreSite } = {}; protected sites: { [s: string]: CoreSite } = {};
protected appDB: SQLiteDB;
protected dbReady: Promise<void>; // Promise resolved when the app DB is initialized.
protected siteSchemasMigration: { [siteId: string]: Promise<void> } = {}; protected siteSchemasMigration: { [siteId: string]: Promise<void> } = {};
protected siteSchemas: { [name: string]: CoreRegisteredSiteSchema } = {}; protected siteSchemas: { [name: string]: CoreRegisteredSiteSchema } = {};
protected pluginsSiteSchemas: { [name: string]: CoreRegisteredSiteSchema } = {}; protected pluginsSiteSchemas: { [name: string]: CoreRegisteredSiteSchema } = {};
// Variables for DB.
protected appDB: Promise<SQLiteDB>;
protected resolveAppDB!: (appDB: SQLiteDB) => void;
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.logger = CoreLogger.getInstance('CoreSitesProvider'); this.logger = CoreLogger.getInstance('CoreSitesProvider');
this.siteSchemas = CoreArray.flatten(siteSchemas).reduce( this.siteSchemas = CoreArray.flatten(siteSchemas).reduce(
(siteSchemas, schema) => { (siteSchemas, schema) => {
@ -89,10 +91,19 @@ export class CoreSitesProvider {
}, },
this.siteSchemas, this.siteSchemas,
); );
this.appDB = CoreApp.instance.getDB(); }
this.dbReady = CoreApp.instance.createTablesFromSchema(APP_SCHEMA).catch(() => {
/**
* Initialise database.
*/
async initialiseDatabase(): Promise<void> {
try {
await CoreApp.instance.createTablesFromSchema(APP_SCHEMA);
} catch (e) {
// Ignore errors. // Ignore errors.
}); }
this.resolveAppDB(CoreApp.instance.getDB());
} }
/** /**
@ -429,7 +440,7 @@ export class CoreSitesProvider {
const info = await candidateSite.fetchSiteInfo(); const info = await candidateSite.fetchSiteInfo();
const result = this.isValidMoodleVersion(info); const result = this.isValidMoodleVersion(info);
if (result != this.VALID_VERSION) { if (result != CoreSitesProvider.VALID_VERSION) {
return this.treatInvalidAppVersion(result, siteUrl); return this.treatInvalidAppVersion(result, siteUrl);
} }
@ -491,7 +502,7 @@ export class CoreSitesProvider {
} catch (error) { } catch (error) {
// Error invaliddevice is returned by Workplace server meaning the same as connecttoworkplaceapp. // Error invaliddevice is returned by Workplace server meaning the same as connecttoworkplaceapp.
if (error && error.errorcode == 'invaliddevice') { if (error && error.errorcode == 'invaliddevice') {
return this.treatInvalidAppVersion(this.WORKPLACE_APP, siteUrl); return this.treatInvalidAppVersion(CoreSitesProvider.WORKPLACE_APP, siteUrl);
} }
throw error; throw error;
@ -512,11 +523,11 @@ export class CoreSitesProvider {
let translateParams; let translateParams;
switch (result) { switch (result) {
case this.MOODLE_APP: case CoreSitesProvider.MOODLE_APP:
errorKey = 'core.login.connecttomoodleapp'; errorKey = 'core.login.connecttomoodleapp';
errorCode = 'connecttomoodleapp'; errorCode = 'connecttomoodleapp';
break; break;
case this.WORKPLACE_APP: case CoreSitesProvider.WORKPLACE_APP:
errorKey = 'core.login.connecttoworkplaceapp'; errorKey = 'core.login.connecttoworkplaceapp';
errorCode = 'connecttoworkplaceapp'; errorCode = 'connecttoworkplaceapp';
break; break;
@ -581,7 +592,7 @@ export class CoreSitesProvider {
*/ */
protected isValidMoodleVersion(info: CoreSiteInfoResponse): number { protected isValidMoodleVersion(info: CoreSiteInfoResponse): number {
if (!info) { if (!info) {
return this.INVALID_VERSION; return CoreSitesProvider.INVALID_VERSION;
} }
const version31 = 2016052300; const version31 = 2016052300;
@ -606,7 +617,7 @@ export class CoreSitesProvider {
} }
// Couldn't validate it. // Couldn't validate it.
return this.INVALID_VERSION; return CoreSitesProvider.INVALID_VERSION;
} }
/** /**
@ -623,14 +634,14 @@ export class CoreSitesProvider {
} }
if (!this.isWPApp && isWorkplace) { if (!this.isWPApp && isWorkplace) {
return this.WORKPLACE_APP; return CoreSitesProvider.WORKPLACE_APP;
} }
if (this.isWPApp && !isWorkplace) { if (this.isWPApp && !isWorkplace) {
return this.MOODLE_APP; return CoreSitesProvider.MOODLE_APP;
} }
return this.VALID_VERSION; return CoreSitesProvider.VALID_VERSION;
} }
/** /**
@ -669,8 +680,7 @@ export class CoreSitesProvider {
config?: CoreSiteConfig, config?: CoreSiteConfig,
oauthId?: number, oauthId?: number,
): Promise<void> { ): Promise<void> {
await this.dbReady; const db = await this.appDB;
const entry = { const entry = {
id, id,
siteUrl, siteUrl,
@ -682,7 +692,7 @@ export class CoreSitesProvider {
oauthId, oauthId,
}; };
await this.appDB.insertRecord(SITES_TABLE_NAME, entry); await db.insertRecord(SITES_TABLE_NAME, entry);
} }
/** /**
@ -893,8 +903,6 @@ export class CoreSitesProvider {
* @return Promise to be resolved when the site is deleted. * @return Promise to be resolved when the site is deleted.
*/ */
async deleteSite(siteId: string): Promise<void> { async deleteSite(siteId: string): Promise<void> {
await this.dbReady;
this.logger.debug(`Delete site ${siteId}`); this.logger.debug(`Delete site ${siteId}`);
if (typeof this.currentSite != 'undefined' && this.currentSite.id == siteId) { if (typeof this.currentSite != 'undefined' && this.currentSite.id == siteId) {
@ -909,7 +917,9 @@ export class CoreSitesProvider {
delete this.sites[siteId]; delete this.sites[siteId];
try { try {
await this.appDB.deleteRecords(SITES_TABLE_NAME, { id: siteId }); const db = await this.appDB;
await db.deleteRecords(SITES_TABLE_NAME, { id: siteId });
} catch (err) { } catch (err) {
// DB remove shouldn't fail, but we'll go ahead even if it does. // DB remove shouldn't fail, but we'll go ahead even if it does.
} }
@ -926,9 +936,8 @@ export class CoreSitesProvider {
* @return Promise resolved with true if there are sites and false if there aren't. * @return Promise resolved with true if there are sites and false if there aren't.
*/ */
async hasSites(): Promise<boolean> { async hasSites(): Promise<boolean> {
await this.dbReady; const db = await this.appDB;
const count = await db.countRecords(SITES_TABLE_NAME);
const count = await this.appDB.countRecords(SITES_TABLE_NAME);
return count > 0; return count > 0;
} }
@ -940,8 +949,6 @@ export class CoreSitesProvider {
* @return Promise resolved with the site. * @return Promise resolved with the site.
*/ */
async getSite(siteId?: string): Promise<CoreSite> { async getSite(siteId?: string): Promise<CoreSite> {
await this.dbReady;
if (!siteId) { if (!siteId) {
if (this.currentSite) { if (this.currentSite) {
return this.currentSite; return this.currentSite;
@ -954,7 +961,8 @@ export class CoreSitesProvider {
return this.sites[siteId]; return this.sites[siteId];
} else { } else {
// Retrieve and create the site. // Retrieve and create the site.
const data = await this.appDB.getRecord<SiteDBEntry>(SITES_TABLE_NAME, { id: siteId }); const db = await this.appDB;
const data = await db.getRecord<SiteDBEntry>(SITES_TABLE_NAME, { id: siteId });
return this.makeSiteFromSiteListEntry(data); return this.makeSiteFromSiteListEntry(data);
} }
@ -1025,9 +1033,8 @@ export class CoreSitesProvider {
* @return Promise resolved when the sites are retrieved. * @return Promise resolved when the sites are retrieved.
*/ */
async getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> { async getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> {
await this.dbReady; const db = await this.appDB;
const sites = await db.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME);
const sites = await this.appDB.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME);
const formattedSites: CoreSiteBasicInfo[] = []; const formattedSites: CoreSiteBasicInfo[] = [];
sites.forEach((site) => { sites.forEach((site) => {
@ -1089,9 +1096,8 @@ export class CoreSitesProvider {
* @return Promise resolved when the sites IDs are retrieved. * @return Promise resolved when the sites IDs are retrieved.
*/ */
async getLoggedInSitesIds(): Promise<string[]> { async getLoggedInSitesIds(): Promise<string[]> {
await this.dbReady; const db = await this.appDB;
const sites = await db.getRecords<SiteDBEntry>(SITES_TABLE_NAME, { loggedOut : 0 });
const sites = await this.appDB.getRecords<SiteDBEntry>(SITES_TABLE_NAME, { loggedOut : 0 });
return sites.map((site) => site.id); return sites.map((site) => site.id);
} }
@ -1102,9 +1108,8 @@ export class CoreSitesProvider {
* @return Promise resolved when the sites IDs are retrieved. * @return Promise resolved when the sites IDs are retrieved.
*/ */
async getSitesIds(): Promise<string[]> { async getSitesIds(): Promise<string[]> {
await this.dbReady; const db = await this.appDB;
const sites = await db.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME);
const sites = await this.appDB.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME);
return sites.map((site) => site.id); return sites.map((site) => site.id);
} }
@ -1116,14 +1121,13 @@ export class CoreSitesProvider {
* @return Promise resolved when current site is stored. * @return Promise resolved when current site is stored.
*/ */
async login(siteId: string): Promise<void> { async login(siteId: string): Promise<void> {
await this.dbReady; const db = await this.appDB;
const entry = { const entry = {
id: 1, id: 1,
siteId, siteId,
}; };
await this.appDB.insertRecord(CURRENT_SITE_TABLE_NAME, entry); await db.insertRecord(CURRENT_SITE_TABLE_NAME, entry);
CoreEvents.trigger(CoreEvents.LOGIN, {}, siteId); CoreEvents.trigger(CoreEvents.LOGIN, {}, siteId);
} }
@ -1134,12 +1138,11 @@ export class CoreSitesProvider {
* @return Promise resolved when the user is logged out. * @return Promise resolved when the user is logged out.
*/ */
async logout(): Promise<void> { async logout(): Promise<void> {
await this.dbReady;
let siteId: string | undefined; let siteId: string | undefined;
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
if (this.currentSite) { if (this.currentSite) {
const db = await this.appDB;
const siteConfig = this.currentSite.getStoredConfig(); const siteConfig = this.currentSite.getStoredConfig();
siteId = this.currentSite.getId(); siteId = this.currentSite.getId();
@ -1149,7 +1152,7 @@ export class CoreSitesProvider {
promises.push(this.setSiteLoggedOut(siteId, true)); promises.push(this.setSiteLoggedOut(siteId, true));
} }
promises.push(this.appDB.deleteRecords(CURRENT_SITE_TABLE_NAME, { id: 1 })); promises.push(db.deleteRecords(CURRENT_SITE_TABLE_NAME, { id: 1 }));
} }
try { try {
@ -1169,12 +1172,12 @@ export class CoreSitesProvider {
return Promise.reject(new CoreError('Session already restored.')); return Promise.reject(new CoreError('Session already restored.'));
} }
await this.dbReady; const db = await this.appDB;
this.sessionRestored = true; this.sessionRestored = true;
try { try {
const currentSite = await this.appDB.getRecord<CurrentSiteDBEntry>(CURRENT_SITE_TABLE_NAME, { id: 1 }); const currentSite = await db.getRecord<CurrentSiteDBEntry>(CURRENT_SITE_TABLE_NAME, { id: 1 });
const siteId = currentSite.siteId; const siteId = currentSite.siteId;
this.logger.debug(`Restore session in site ${siteId}`); this.logger.debug(`Restore session in site ${siteId}`);
@ -1192,8 +1195,7 @@ export class CoreSitesProvider {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async setSiteLoggedOut(siteId: string, loggedOut: boolean): Promise<void> { async setSiteLoggedOut(siteId: string, loggedOut: boolean): Promise<void> {
await this.dbReady; const db = await this.appDB;
const site = await this.getSite(siteId); const site = await this.getSite(siteId);
const newValues = { const newValues = {
token: '', // Erase the token for security. token: '', // Erase the token for security.
@ -1202,7 +1204,7 @@ export class CoreSitesProvider {
site.setLoggedOut(loggedOut); site.setLoggedOut(loggedOut);
await this.appDB.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId }); await db.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId });
} }
/** /**
@ -1238,8 +1240,7 @@ export class CoreSitesProvider {
* @return A promise resolved when the site is updated. * @return A promise resolved when the site is updated.
*/ */
async updateSiteTokenBySiteId(siteId: string, token: string, privateToken: string = ''): Promise<void> { async updateSiteTokenBySiteId(siteId: string, token: string, privateToken: string = ''): Promise<void> {
await this.dbReady; const db = await this.appDB;
const site = await this.getSite(siteId); const site = await this.getSite(siteId);
const newValues = { const newValues = {
token, token,
@ -1251,7 +1252,7 @@ export class CoreSitesProvider {
site.privateToken = privateToken; site.privateToken = privateToken;
site.setLoggedOut(false); // Token updated means the user authenticated again, not logged out anymore. site.setLoggedOut(false); // Token updated means the user authenticated again, not logged out anymore.
await this.appDB.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId }); await db.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId });
} }
/** /**
@ -1261,8 +1262,6 @@ export class CoreSitesProvider {
* @return A promise resolved when the site is updated. * @return A promise resolved when the site is updated.
*/ */
async updateSiteInfo(siteId: string): Promise<void> { async updateSiteInfo(siteId: string): Promise<void> {
await this.dbReady;
const site = await this.getSite(siteId); const site = await this.getSite(siteId);
try { try {
@ -1270,7 +1269,7 @@ export class CoreSitesProvider {
site.setInfo(info); site.setInfo(info);
const versionCheck = this.isValidMoodleVersion(info); const versionCheck = this.isValidMoodleVersion(info);
if (versionCheck != this.VALID_VERSION) { if (versionCheck != CoreSitesProvider.VALID_VERSION) {
// The Moodle version is not supported, reject. // The Moodle version is not supported, reject.
return this.treatInvalidAppVersion(versionCheck, site.getURL(), site.getId()); return this.treatInvalidAppVersion(versionCheck, site.getURL(), site.getId());
} }
@ -1295,7 +1294,9 @@ export class CoreSitesProvider {
} }
try { try {
await this.appDB.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId }); const db = await this.appDB;
await db.updateRecords(SITES_TABLE_NAME, newValues, { id: siteId });
} finally { } finally {
CoreEvents.trigger(CoreEvents.SITE_UPDATED, info, siteId); CoreEvents.trigger(CoreEvents.SITE_UPDATED, info, siteId);
} }
@ -1328,8 +1329,6 @@ export class CoreSitesProvider {
* @return Promise resolved with the site IDs (array). * @return Promise resolved with the site IDs (array).
*/ */
async getSiteIdsFromUrl(url: string, prioritize?: boolean, username?: string): Promise<string[]> { async getSiteIdsFromUrl(url: string, prioritize?: boolean, username?: string): Promise<string[]> {
await this.dbReady;
// If prioritize is true, check current site first. // If prioritize is true, check current site first.
if (prioritize && this.currentSite && this.currentSite.containsUrl(url)) { if (prioritize && this.currentSite && this.currentSite.containsUrl(url)) {
if (!username || this.currentSite?.getInfo()?.username == username) { if (!username || this.currentSite?.getInfo()?.username == username) {
@ -1354,7 +1353,8 @@ export class CoreSitesProvider {
} }
try { try {
const siteEntries = await this.appDB.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME); const db = await this.appDB;
const siteEntries = await db.getAllRecords<SiteDBEntry>(SITES_TABLE_NAME);
const ids: string[] = []; const ids: string[] = [];
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
@ -1385,9 +1385,8 @@ export class CoreSitesProvider {
* @return Promise resolved with the site ID. * @return Promise resolved with the site ID.
*/ */
async getStoredCurrentSiteId(): Promise<string> { async getStoredCurrentSiteId(): Promise<string> {
await this.dbReady; const db = await this.appDB;
const currentSite = await db.getRecord<CurrentSiteDBEntry>(CURRENT_SITE_TABLE_NAME, { id: 1 });
const currentSite = await this.appDB.getRecord<CurrentSiteDBEntry>(CURRENT_SITE_TABLE_NAME, { id: 1 });
return currentSite.siteId; return currentSite.siteId;
} }

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { SYNC_TABLE_NAME, CoreSyncRecord } from '@services/db/sync'; import { SYNC_TABLE_NAME, CoreSyncRecord } from '@services/database/sync';
/* /*
* Service that provides some features regarding synchronization. * Service that provides some features regarding synchronization.