MOBILE-3981 pushnotifications: Optimize tables

main
Noel De Martin 2022-02-10 15:57:02 +01:00
parent 18c48940bf
commit 84307d6f70
1 changed files with 56 additions and 39 deletions

View File

@ -24,7 +24,6 @@ import { CoreUtils } from '@services/utils/utils';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { SQLiteDB } from '@classes/sqlitedb';
import { CoreSite, CoreSiteInfo } from '@classes/site'; import { CoreSite, CoreSiteInfo } from '@classes/site';
import { makeSingleton, Badge, Push, Device, Translate, Platform, ApplicationInit, NgZone } from '@singletons'; import { makeSingleton, Badge, Push, Device, Translate, Platform, ApplicationInit, NgZone } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
@ -42,6 +41,11 @@ import { CoreError } from '@classes/errors/error';
import { CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalWarning } from '@services/ws';
import { CoreSitesFactory } from '@services/sites-factory'; import { CoreSitesFactory } from '@services/sites-factory';
import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu'; import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu';
import { AsyncInstance, asyncInstance } from '@/core/utils/async-instance';
import { CoreDatabaseTable } from '@classes/database/database-table';
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
import { CoreObject } from '@singletons/object';
import { lazyMap, LazyMap } from '@/core/utils/lazy-map';
/** /**
* Service to handle push notifications. * Service to handle push notifications.
@ -53,14 +57,27 @@ export class CorePushNotificationsProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected pushID?: string; protected pushID?: string;
protected badgesTable = asyncInstance<CoreDatabaseTable<CorePushNotificationsBadgeDBRecord, 'siteid' | 'addon'>>();
protected pendingUnregistersTable =
asyncInstance<CoreDatabaseTable<CorePushNotificationsPendingUnregisterDBRecord, 'siteid'>>();
// Variables for DB. protected registeredDevicesTables:
protected appDB: Promise<SQLiteDB>; LazyMap<AsyncInstance<CoreDatabaseTable<CorePushNotificationsRegisteredDeviceDBRecord, 'appid' | 'uuid'>>>;
protected resolveAppDB!: (appDB: SQLiteDB) => void;
constructor() { constructor() {
this.appDB = new Promise(resolve => this.resolveAppDB = resolve);
this.logger = CoreLogger.getInstance('CorePushNotificationsProvider'); this.logger = CoreLogger.getInstance('CorePushNotificationsProvider');
this.registeredDevicesTables = lazyMap(
siteId => asyncInstance(
() => CoreSites.getSiteTable<CorePushNotificationsRegisteredDeviceDBRecord, 'appid' | 'uuid'>(
REGISTERED_DEVICES_TABLE_NAME,
{
siteId,
config: { cachingStrategy: CoreDatabaseCachingStrategy.None },
primaryKeyColumns: ['appid', 'uuid'],
},
),
),
);
} }
/** /**
@ -157,7 +174,27 @@ export class CorePushNotificationsProvider {
// Ignore errors. // Ignore errors.
} }
this.resolveAppDB(CoreApp.getDB()); const database = CoreApp.getDB();
const badgesTable = new CoreDatabaseTableProxy<CorePushNotificationsBadgeDBRecord, 'siteid' | 'addon'>(
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
database,
BADGE_TABLE_NAME,
['siteid', 'addon'],
);
const pendingUnregistersTable = new CoreDatabaseTableProxy<CorePushNotificationsPendingUnregisterDBRecord, 'siteid'>(
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
database,
PENDING_UNREGISTER_TABLE_NAME,
['siteid'],
);
await Promise.all([
badgesTable.initialize(),
pendingUnregistersTable.initialize(),
]);
this.badgesTable.setInstance(badgesTable);
this.pendingUnregistersTable.setInstance(pendingUnregistersTable);
} }
/** /**
@ -177,8 +214,7 @@ export class CorePushNotificationsProvider {
*/ */
async cleanSiteCounters(siteId: string): Promise<void> { async cleanSiteCounters(siteId: string): Promise<void> {
try { try {
const db = await this.appDB; await this.badgesTable.delete({ siteid: siteId });
await db.deleteRecords(BADGE_TABLE_NAME, { siteid: siteId } );
} finally { } finally {
this.updateAppCounter(); this.updateAppCounter();
} }
@ -514,7 +550,6 @@ export class CorePushNotificationsProvider {
this.logger.debug(`Unregister device on Moodle: '${site.getId()}'`); this.logger.debug(`Unregister device on Moodle: '${site.getId()}'`);
const db = await this.appDB;
const data: CoreUserRemoveUserDeviceWSParams = { const data: CoreUserRemoveUserDeviceWSParams = {
appid: CoreConstants.CONFIG.app_id, appid: CoreConstants.CONFIG.app_id,
uuid: Device.uuid, uuid: Device.uuid,
@ -526,7 +561,7 @@ export class CorePushNotificationsProvider {
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error) || CoreUtils.isExpiredTokenError(error)) { if (CoreUtils.isWebServiceError(error) || CoreUtils.isExpiredTokenError(error)) {
// Cannot unregister. Don't try again. // Cannot unregister. Don't try again.
await CoreUtils.ignoreErrors(db.deleteRecords(PENDING_UNREGISTER_TABLE_NAME, { await CoreUtils.ignoreErrors(this.pendingUnregistersTable.delete({
token: site.getToken(), token: site.getToken(),
siteid: site.getId(), siteid: site.getId(),
})); }));
@ -535,13 +570,12 @@ export class CorePushNotificationsProvider {
} }
// Store the pending unregister so it's retried again later. // Store the pending unregister so it's retried again later.
const entry: CorePushNotificationsPendingUnregisterDBRecord = { await this.pendingUnregistersTable.insert({
siteid: site.getId(), siteid: site.getId(),
siteurl: site.getURL(), siteurl: site.getURL(),
token: site.getToken(), token: site.getToken(),
info: JSON.stringify(site.getInfo()), info: JSON.stringify(site.getInfo()),
}; });
await db.insertRecord(PENDING_UNREGISTER_TABLE_NAME, entry);
return; return;
} }
@ -552,9 +586,9 @@ export class CorePushNotificationsProvider {
await CoreUtils.ignoreErrors(Promise.all([ await CoreUtils.ignoreErrors(Promise.all([
// Remove the device from the local DB. // Remove the device from the local DB.
site.getDb().deleteRecords(REGISTERED_DEVICES_TABLE_NAME, this.getRegisterData()), this.registeredDevicesTables[site.getId()].delete(this.getRegisterData()),
// Remove pending unregisters for this site. // Remove pending unregisters for this site.
db.deleteRecords(PENDING_UNREGISTER_TABLE_NAME, { siteid: site.getId() }), this.pendingUnregistersTable.deleteByPrimaryKey({ siteid: site.getId() }),
])); ]));
} }
@ -714,15 +748,14 @@ export class CorePushNotificationsProvider {
// Insert the device in the local DB. // Insert the device in the local DB.
try { try {
await site.getDb().insertRecord(REGISTERED_DEVICES_TABLE_NAME, data); await this.registeredDevicesTables[site.getId()].insert(data);
} catch (err) { } catch (err) {
// Ignore errors. // Ignore errors.
} }
} }
} finally { } finally {
// Remove pending unregisters for this site. // Remove pending unregisters for this site.
const db = await this.appDB; await CoreUtils.ignoreErrors(this.pendingUnregistersTable.deleteByPrimaryKey({ siteid: site.getId() }));
await CoreUtils.ignoreErrors(db.deleteRecords(PENDING_UNREGISTER_TABLE_NAME, { siteid: site.getId() }));
} }
} }
@ -735,8 +768,7 @@ export class CorePushNotificationsProvider {
*/ */
protected async getAddonBadge(siteId?: string, addon: string = 'site'): Promise<number> { protected async getAddonBadge(siteId?: string, addon: string = 'site'): Promise<number> {
try { try {
const db = await this.appDB; const entry = await this.badgesTable.getOne({ siteid: siteId, addon });
const entry = await db.getRecord<CorePushNotificationsBadgeDBRecord>(BADGE_TABLE_NAME, { siteid: siteId, addon });
return entry?.number || 0; return entry?.number || 0;
} catch (err) { } catch (err) {
@ -751,19 +783,7 @@ export class CorePushNotificationsProvider {
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
async retryUnregisters(siteId?: string): Promise<void> { async retryUnregisters(siteId?: string): Promise<void> {
const results = await this.pendingUnregistersTable.getMany(CoreObject.withoutEmpty({ siteid: siteId }));
const db = await this.appDB;
let results: CorePushNotificationsPendingUnregisterDBRecord[];
if (siteId) {
// Check if the site has a pending unregister.
results = await db.getRecords<CorePushNotificationsPendingUnregisterDBRecord>(PENDING_UNREGISTER_TABLE_NAME, {
siteid: siteId,
});
} else {
// Get all pending unregisters.
results = await db.getAllRecords<CorePushNotificationsPendingUnregisterDBRecord>(PENDING_UNREGISTER_TABLE_NAME);
}
await Promise.all(results.map(async (result) => { await Promise.all(results.map(async (result) => {
// Create a temporary site to unregister. // Create a temporary site to unregister.
@ -789,14 +809,11 @@ export class CorePushNotificationsProvider {
protected async saveAddonBadge(value: number, siteId?: string, addon: string = 'site'): Promise<number> { protected async saveAddonBadge(value: number, siteId?: string, addon: string = 'site'): Promise<number> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const entry: CorePushNotificationsBadgeDBRecord = { await this.badgesTable.insert({
siteid: siteId, siteid: siteId,
addon, addon,
number: value, // eslint-disable-line id-blacklist number: value, // eslint-disable-line id-blacklist
}; });
const db = await this.appDB;
await db.insertRecord(BADGE_TABLE_NAME, entry);
return value; return value;
} }
@ -815,7 +832,7 @@ export class CorePushNotificationsProvider {
// Check if the device is already registered. // Check if the device is already registered.
const records = await CoreUtils.ignoreErrors( const records = await CoreUtils.ignoreErrors(
site.getDb().getRecords<CorePushNotificationsRegisteredDeviceDBRecord>(REGISTERED_DEVICES_TABLE_NAME, { this.registeredDevicesTables[site.getId()].getMany({
appid: data.appid, appid: data.appid,
uuid: data.uuid, uuid: data.uuid,
name: data.name, name: data.name,