MOBILE-2853 core: Let app DB tables define a scheme to handle updates
parent
84f559264b
commit
80c2aef0d0
|
@ -170,7 +170,7 @@ interface RequestQueueItem {
|
||||||
/**
|
/**
|
||||||
* Class that represents a site (combination of site + user).
|
* Class that represents a site (combination of site + user).
|
||||||
* It will have all the site data and provide utility functions regarding a site.
|
* It will have all the site data and provide utility functions regarding a site.
|
||||||
* To add tables to the site's database, please use CoreSitesProvider.createTablesFromSchema. This will make sure that
|
* To add tables to the site's database, please use CoreSitesProvider.registerSiteSchema. This will make sure that
|
||||||
* the tables are created in all the sites, not just the current one.
|
* the tables are created in all the sites, not just the current one.
|
||||||
*/
|
*/
|
||||||
export class CoreSite {
|
export class CoreSite {
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { LocalNotifications, ILocalNotification, ILocalNotificationAction } from '@ionic-native/local-notifications';
|
import { LocalNotifications, ILocalNotification, ILocalNotificationAction } from '@ionic-native/local-notifications';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider, CoreAppSchema } from '@providers/app';
|
||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreConfigConstants } from '../../../configconstants';
|
import { CoreConfigConstants } from '../../../configconstants';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
@ -43,7 +43,11 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
|
|
||||||
// Variables for database.
|
// Variables for database.
|
||||||
protected DESKTOP_NOTIFS_TABLE = 'desktop_local_notifications';
|
protected DESKTOP_NOTIFS_TABLE = 'desktop_local_notifications';
|
||||||
protected tableSchema: SQLiteDBTableSchema = {
|
protected tableSchema: CoreAppSchema = {
|
||||||
|
name: 'LocalNotificationsMock',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
name: this.DESKTOP_NOTIFS_TABLE,
|
name: this.DESKTOP_NOTIFS_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
@ -71,13 +75,16 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
name: 'triggered',
|
name: 'triggered',
|
||||||
type: 'INTEGER'
|
type: 'INTEGER'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
protected scheduled: { [i: number]: any } = {};
|
protected scheduled: { [i: number]: any } = {};
|
||||||
protected triggered: { [i: number]: any } = {};
|
protected triggered: { [i: number]: any } = {};
|
||||||
protected observers: {[event: string]: Subject<any>};
|
protected observers: {[event: string]: Subject<any>};
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
protected defaults = {
|
protected defaults = {
|
||||||
actions : [],
|
actions : [],
|
||||||
attachments : [],
|
attachments : [],
|
||||||
|
@ -117,7 +124,9 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTableFromSchema(this.tableSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.tableSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize observers.
|
// Initialize observers.
|
||||||
this.observers = {
|
this.observers = {
|
||||||
|
@ -550,8 +559,10 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*
|
*
|
||||||
* @return Promise resolved with the notifications.
|
* @return Promise resolved with the notifications.
|
||||||
*/
|
*/
|
||||||
protected getAllNotifications(): Promise<any> {
|
protected async getAllNotifications(): Promise<any> {
|
||||||
return this.appDB.getAllRecords(this.DESKTOP_NOTIFS_TABLE).then((notifications) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const notifications = await this.appDB.getAllRecords(this.DESKTOP_NOTIFS_TABLE);
|
||||||
notifications.forEach((notification) => {
|
notifications.forEach((notification) => {
|
||||||
notification.trigger = {
|
notification.trigger = {
|
||||||
at: new Date(notification.at)
|
at: new Date(notification.at)
|
||||||
|
@ -563,7 +574,6 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
});
|
});
|
||||||
|
|
||||||
return notifications;
|
return notifications;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -889,7 +899,9 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
* @param id ID of the notification.
|
* @param id ID of the notification.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected removeNotification(id: number): Promise<any> {
|
protected async removeNotification(id: number): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.DESKTOP_NOTIFS_TABLE, { id: id });
|
return this.appDB.deleteRecords(this.DESKTOP_NOTIFS_TABLE, { id: id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +991,9 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
* @param triggered Whether the notification has been triggered.
|
* @param triggered Whether the notification has been triggered.
|
||||||
* @return Promise resolved when stored.
|
* @return Promise resolved when stored.
|
||||||
*/
|
*/
|
||||||
protected storeNotification(notification: ILocalNotification, triggered: boolean): Promise<any> {
|
protected async storeNotification(notification: ILocalNotification, triggered: boolean): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
// Only store some of the properties.
|
// Only store some of the properties.
|
||||||
const entry = {
|
const entry = {
|
||||||
id : notification.id,
|
id : notification.id,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { Badge } from '@ionic-native/badge';
|
||||||
import { Push, PushObject, PushOptions } from '@ionic-native/push';
|
import { Push, PushObject, PushOptions } from '@ionic-native/push';
|
||||||
import { Device } from '@ionic-native/device';
|
import { Device } from '@ionic-native/device';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider, CoreAppSchema } from '@providers/app';
|
||||||
import { CoreInitDelegate } from '@providers/init';
|
import { CoreInitDelegate } from '@providers/init';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites';
|
import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites';
|
||||||
|
@ -31,7 +31,7 @@ import { CoreConfigProvider } from '@providers/config';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreConfigConstants } from '../../../configconstants';
|
import { CoreConfigConstants } from '../../../configconstants';
|
||||||
import { ILocalNotification } from '@ionic-native/local-notifications';
|
import { ILocalNotification } from '@ionic-native/local-notifications';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite } from '@classes/site';
|
||||||
import { CoreFilterProvider } from '@core/filter/providers/filter';
|
import { CoreFilterProvider } from '@core/filter/providers/filter';
|
||||||
import { CoreFilterDelegate } from '@core/filter/providers/delegate';
|
import { CoreFilterDelegate } from '@core/filter/providers/delegate';
|
||||||
|
@ -84,13 +84,17 @@ export class CorePushNotificationsProvider {
|
||||||
protected logger;
|
protected logger;
|
||||||
protected pushID: string;
|
protected pushID: string;
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
static COMPONENT = 'CorePushNotificationsProvider';
|
static COMPONENT = 'CorePushNotificationsProvider';
|
||||||
|
|
||||||
// Variables for database. The name still contains the name "addon" for backwards compatibility.
|
// Variables for database. The name still contains the name "addon" for backwards compatibility.
|
||||||
static BADGE_TABLE = 'addon_pushnotifications_badge';
|
static BADGE_TABLE = 'addon_pushnotifications_badge';
|
||||||
static PENDING_UNREGISTER_TABLE = 'addon_pushnotifications_pending_unregister';
|
static PENDING_UNREGISTER_TABLE = 'addon_pushnotifications_pending_unregister';
|
||||||
static REGISTERED_DEVICES_TABLE = 'addon_pushnotifications_registered_devices';
|
static REGISTERED_DEVICES_TABLE = 'addon_pushnotifications_registered_devices';
|
||||||
protected appTablesSchema: SQLiteDBTableSchema[] = [
|
protected appTablesSchema: CoreAppSchema = {
|
||||||
|
name: 'CorePushNotificationsProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
{
|
{
|
||||||
name: CorePushNotificationsProvider.BADGE_TABLE,
|
name: CorePushNotificationsProvider.BADGE_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -131,7 +135,8 @@ export class CorePushNotificationsProvider {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
};
|
||||||
protected siteSchema: CoreSiteSchema = {
|
protected siteSchema: CoreSiteSchema = {
|
||||||
name: 'AddonPushNotificationsProvider', // The name still contains "Addon" for backwards compatibility.
|
name: 'AddonPushNotificationsProvider', // The name still contains "Addon" for backwards compatibility.
|
||||||
version: 1,
|
version: 1,
|
||||||
|
@ -182,7 +187,9 @@ export class CorePushNotificationsProvider {
|
||||||
private filterProvider: CoreFilterProvider, private filterDelegate: CoreFilterDelegate) {
|
private filterProvider: CoreFilterProvider, private filterDelegate: CoreFilterDelegate) {
|
||||||
this.logger = logger.getInstance('CorePushNotificationsProvider');
|
this.logger = logger.getInstance('CorePushNotificationsProvider');
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTablesFromSchema(this.appTablesSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.appTablesSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
||||||
|
|
||||||
platform.ready().then(() => {
|
platform.ready().then(() => {
|
||||||
|
@ -211,10 +218,14 @@ export class CorePushNotificationsProvider {
|
||||||
* @param siteId Site ID.
|
* @param siteId Site ID.
|
||||||
* @return Resolved when done.
|
* @return Resolved when done.
|
||||||
*/
|
*/
|
||||||
cleanSiteCounters(siteId: string): Promise<any> {
|
async cleanSiteCounters(siteId: string): Promise<void> {
|
||||||
return this.appDB.deleteRecords(CorePushNotificationsProvider.BADGE_TABLE, {siteid: siteId} ).finally(() => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.appDB.deleteRecords(CorePushNotificationsProvider.BADGE_TABLE, {siteid: siteId} );
|
||||||
|
} finally {
|
||||||
this.updateAppCounter();
|
this.updateAppCounter();
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -532,11 +543,13 @@ export class CorePushNotificationsProvider {
|
||||||
* @param site Site to unregister from.
|
* @param site Site to unregister from.
|
||||||
* @return Promise resolved when device is unregistered.
|
* @return Promise resolved when device is unregistered.
|
||||||
*/
|
*/
|
||||||
unregisterDeviceOnMoodle(site: CoreSite): Promise<any> {
|
async unregisterDeviceOnMoodle(site: CoreSite): Promise<any> {
|
||||||
if (!site || !this.appProvider.isMobile()) {
|
if (!site || !this.appProvider.isMobile()) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
this.logger.debug(`Unregister device on Moodle: '${site.id}'`);
|
this.logger.debug(`Unregister device on Moodle: '${site.id}'`);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
@ -544,9 +557,11 @@ export class CorePushNotificationsProvider {
|
||||||
uuid: this.device.uuid
|
uuid: this.device.uuid
|
||||||
};
|
};
|
||||||
|
|
||||||
return site.write('core_user_remove_user_device', data).then((response) => {
|
try {
|
||||||
|
const response = await site.write('core_user_remove_user_device', data);
|
||||||
|
|
||||||
if (!response || !response.removed) {
|
if (!response || !response.removed) {
|
||||||
return Promise.reject(null);
|
throw null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
@ -561,24 +576,21 @@ export class CorePushNotificationsProvider {
|
||||||
return Promise.all(promises).catch(() => {
|
return Promise.all(promises).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
});
|
});
|
||||||
}).catch((error) => {
|
} catch (error) {
|
||||||
if (this.utils.isWebServiceError(error)) {
|
if (!this.utils.isWebServiceError(error)) {
|
||||||
// It's a WebService error, can't unregister.
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the pending unregister so it's retried again later.
|
// Store the pending unregister so it's retried again later.
|
||||||
return this.appDB.insertRecord(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {
|
await this.appDB.insertRecord(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {
|
||||||
siteid: site.id,
|
siteid: site.id,
|
||||||
siteurl: site.getURL(),
|
siteurl: site.getURL(),
|
||||||
token: site.getToken(),
|
token: site.getToken(),
|
||||||
info: JSON.stringify(site.getInfo())
|
info: JSON.stringify(site.getInfo())
|
||||||
}).then(() => {
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Counter for an addon. It will update the refered siteId counter and the total badge.
|
* Update Counter for an addon. It will update the refered siteId counter and the total badge.
|
||||||
* It will return the updated addon counter.
|
* It will return the updated addon counter.
|
||||||
|
@ -724,52 +736,53 @@ export class CorePushNotificationsProvider {
|
||||||
* @param forceUnregister Whether to force unregister and register.
|
* @param forceUnregister Whether to force unregister and register.
|
||||||
* @return Promise resolved when device is registered.
|
* @return Promise resolved when device is registered.
|
||||||
*/
|
*/
|
||||||
registerDeviceOnMoodle(siteId?: string, forceUnregister?: boolean): Promise<any> {
|
async registerDeviceOnMoodle(siteId?: string, forceUnregister?: boolean): Promise<void> {
|
||||||
this.logger.debug('Register device on Moodle.');
|
this.logger.debug('Register device on Moodle.');
|
||||||
|
|
||||||
if (!this.canRegisterOnMoodle()) {
|
if (!this.canRegisterOnMoodle()) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = this.getRegisterData();
|
await this.dbReady;
|
||||||
let result,
|
|
||||||
site: CoreSite;
|
|
||||||
|
|
||||||
return this.sitesProvider.getSite(siteId).then((s) => {
|
const data = this.getRegisterData();
|
||||||
site = s;
|
let result;
|
||||||
|
|
||||||
|
const site = await this.sitesProvider.getSite(siteId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
if (forceUnregister) {
|
if (forceUnregister) {
|
||||||
return {unregister: true, register: true};
|
result = {unregister: true, register: true};
|
||||||
} else {
|
} else {
|
||||||
// Check if the device is already registered.
|
// Check if the device is already registered.
|
||||||
return this.shouldRegister(data, site);
|
result = await this.shouldRegister(data, site);
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
|
||||||
result = res;
|
|
||||||
|
|
||||||
if (result.unregister) {
|
if (result.unregister) {
|
||||||
// Unregister the device first.
|
// Unregister the device first.
|
||||||
return this.unregisterDeviceOnMoodle(site).catch(() => {
|
await this.unregisterDeviceOnMoodle(site).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).then(() => {
|
|
||||||
if (result.register) {
|
if (result.register) {
|
||||||
// Now register the device.
|
// Now register the device.
|
||||||
return site.write('core_user_add_user_device', this.utils.clone(data)).then((response) => {
|
await site.write('core_user_add_user_device', this.utils.clone(data));
|
||||||
|
|
||||||
// Insert the device in the local DB.
|
// Insert the device in the local DB.
|
||||||
return site.getDb().insertRecord(CorePushNotificationsProvider.REGISTERED_DEVICES_TABLE, data)
|
try {
|
||||||
.catch((error) => {
|
await site.getDb().insertRecord(CorePushNotificationsProvider.REGISTERED_DEVICES_TABLE, data);
|
||||||
|
} catch (err) {
|
||||||
|
// Ignore errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Remove pending unregisters for this site.
|
||||||
|
await this.appDB.deleteRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {siteid: site.id}).catch(() => {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
|
||||||
// Remove pending unregisters for this site.
|
|
||||||
this.appDB.deleteRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {siteid: site.id}).catch(() => {
|
|
||||||
// Ignore errors.
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -779,12 +792,16 @@ export class CorePushNotificationsProvider {
|
||||||
* @param addon Registered addon name. If not defined it will store the site total.
|
* @param addon Registered addon name. If not defined it will store the site total.
|
||||||
* @return Promise resolved with the stored badge counter for the addon or site or 0 if none.
|
* @return Promise resolved with the stored badge counter for the addon or site or 0 if none.
|
||||||
*/
|
*/
|
||||||
protected getAddonBadge(siteId?: string, addon: string = 'site'): Promise<any> {
|
protected async getAddonBadge(siteId?: string, addon: string = 'site'): Promise<number> {
|
||||||
return this.appDB.getRecord(CorePushNotificationsProvider.BADGE_TABLE, {siteid: siteId, addon: addon}).then((entry) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const entry = await this.appDB.getRecord(CorePushNotificationsProvider.BADGE_TABLE, {siteid: siteId, addon: addon});
|
||||||
|
|
||||||
return (entry && entry.number) || 0;
|
return (entry && entry.number) || 0;
|
||||||
}).catch(() => {
|
} catch (err) {
|
||||||
return 0;
|
return 0;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -793,30 +810,26 @@ export class CorePushNotificationsProvider {
|
||||||
* @param siteId If defined, retry only for that site if needed. Otherwise, retry all pending unregisters.
|
* @param siteId If defined, retry only for that site if needed. Otherwise, retry all pending unregisters.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
retryUnregisters(siteId?: string): Promise<any> {
|
async retryUnregisters(siteId?: string): Promise<any> {
|
||||||
let promise;
|
await this.dbReady;
|
||||||
|
|
||||||
|
let results;
|
||||||
|
|
||||||
if (siteId) {
|
if (siteId) {
|
||||||
// Check if the site has a pending unregister.
|
// Check if the site has a pending unregister.
|
||||||
promise = this.appDB.getRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {siteid: siteId});
|
results = await this.appDB.getRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {siteid: siteId});
|
||||||
} else {
|
} else {
|
||||||
// Get all pending unregisters.
|
// Get all pending unregisters.
|
||||||
promise = this.appDB.getAllRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE);
|
results = await this.appDB.getAllRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.then((results) => {
|
return Promise.all(results.map((result) => {
|
||||||
const promises = [];
|
|
||||||
|
|
||||||
results.forEach((result) => {
|
|
||||||
// Create a temporary site to unregister.
|
// Create a temporary site to unregister.
|
||||||
const tmpSite = this.sitesFactory.makeSite(result.siteid, result.siteurl, result.token,
|
const tmpSite = this.sitesFactory.makeSite(result.siteid, result.siteurl, result.token,
|
||||||
this.textUtils.parseJSON(result.info, {}));
|
this.textUtils.parseJSON(result.info, {}));
|
||||||
|
|
||||||
promises.push(this.unregisterDeviceOnMoodle(tmpSite));
|
return this.unregisterDeviceOnMoodle(tmpSite);
|
||||||
});
|
}));
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -827,7 +840,9 @@ export class CorePushNotificationsProvider {
|
||||||
* @param addon Registered addon name. If not defined it will store the site total.
|
* @param addon Registered addon name. If not defined it will store the site total.
|
||||||
* @return Promise resolved with the stored badge counter for the addon or site.
|
* @return Promise resolved with the stored badge counter for the addon or site.
|
||||||
*/
|
*/
|
||||||
protected saveAddonBadge(value: number, siteId?: string, addon: string = 'site'): Promise<any> {
|
protected async saveAddonBadge(value: number, siteId?: string, addon: string = 'site'): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
|
@ -836,9 +851,9 @@ export class CorePushNotificationsProvider {
|
||||||
number: value
|
number: value
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.appDB.insertRecord(CorePushNotificationsProvider.BADGE_TABLE, entry).then(() => {
|
await this.appDB.insertRecord(CorePushNotificationsProvider.BADGE_TABLE, entry);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider, CoreAppSchema } from '@providers/app';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreFileProvider } from '@providers/file';
|
import { CoreFileProvider } from '@providers/file';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
@ -21,7 +21,7 @@ import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to share files with the app.
|
* Service to share files with the app.
|
||||||
|
@ -32,19 +32,26 @@ export class CoreSharedFilesProvider {
|
||||||
|
|
||||||
// Variables for the database.
|
// Variables for the database.
|
||||||
protected SHARED_FILES_TABLE = 'shared_files';
|
protected SHARED_FILES_TABLE = 'shared_files';
|
||||||
protected tableSchema: SQLiteDBTableSchema = {
|
protected tableSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreSharedFilesProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
name: this.SHARED_FILES_TABLE,
|
name: this.SHARED_FILES_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'id',
|
name: 'id',
|
||||||
type: 'TEXT',
|
type: 'TEXT',
|
||||||
primaryKey: true
|
primaryKey: true
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private fileProvider: CoreFileProvider, appProvider: CoreAppProvider,
|
constructor(logger: CoreLoggerProvider, private fileProvider: CoreFileProvider, appProvider: CoreAppProvider,
|
||||||
private textUtils: CoreTextUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider,
|
private textUtils: CoreTextUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider,
|
||||||
|
@ -52,7 +59,9 @@ export class CoreSharedFilesProvider {
|
||||||
this.logger = logger.getInstance('CoreSharedFilesProvider');
|
this.logger = logger.getInstance('CoreSharedFilesProvider');
|
||||||
|
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTableFromSchema(this.tableSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.tableSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +198,9 @@ export class CoreSharedFilesProvider {
|
||||||
* @param fileId File ID.
|
* @param fileId File ID.
|
||||||
* @return Resolved if treated, rejected otherwise.
|
* @return Resolved if treated, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
protected isFileTreated(fileId: string): Promise<any> {
|
protected async isFileTreated(fileId: string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.getRecord(this.SHARED_FILES_TABLE, { id: fileId });
|
return this.appDB.getRecord(this.SHARED_FILES_TABLE, { id: fileId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,12 +210,16 @@ export class CoreSharedFilesProvider {
|
||||||
* @param fileId File ID.
|
* @param fileId File ID.
|
||||||
* @return Promise resolved when marked.
|
* @return Promise resolved when marked.
|
||||||
*/
|
*/
|
||||||
protected markAsTreated(fileId: string): Promise<any> {
|
protected async markAsTreated(fileId: string): Promise<void> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
|
try {
|
||||||
// Check if it's already marked.
|
// Check if it's already marked.
|
||||||
return this.isFileTreated(fileId).catch(() => {
|
await this.isFileTreated(fileId);
|
||||||
|
} catch (err) {
|
||||||
// Doesn't exist, insert it.
|
// Doesn't exist, insert it.
|
||||||
return this.appDB.insertRecord(this.SHARED_FILES_TABLE, { id: fileId });
|
await this.appDB.insertRecord(this.SHARED_FILES_TABLE, { id: fileId });
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,7 +258,9 @@ export class CoreSharedFilesProvider {
|
||||||
* @param fileId File ID.
|
* @param fileId File ID.
|
||||||
* @return Resolved when unmarked.
|
* @return Resolved when unmarked.
|
||||||
*/
|
*/
|
||||||
protected unmarkAsTreated(fileId: string): Promise<any> {
|
protected async unmarkAsTreated(fileId: string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.SHARED_FILES_TABLE, { id: fileId });
|
return this.appDB.deleteRecords(this.SHARED_FILES_TABLE, { id: fileId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { StatusBar } from '@ionic-native/status-bar';
|
||||||
import { CoreDbProvider } from './db';
|
import { CoreDbProvider } from './db';
|
||||||
import { CoreLoggerProvider } from './logger';
|
import { CoreLoggerProvider } from './logger';
|
||||||
import { CoreEventsProvider } from './events';
|
import { CoreEventsProvider } from './events';
|
||||||
import { SQLiteDB } from '@classes/sqlitedb';
|
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
import { CoreConfigConstants } from '../configconstants';
|
import { CoreConfigConstants } from '../configconstants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +49,37 @@ export interface CoreRedirectData {
|
||||||
timemodified?: number;
|
timemodified?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App DB schema and migration function.
|
||||||
|
*/
|
||||||
|
export interface CoreAppSchema {
|
||||||
|
/**
|
||||||
|
* Name of the schema.
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Latest version of the schema (integer greater than 0).
|
||||||
|
*/
|
||||||
|
version: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tables to create when installing or upgrading the schema.
|
||||||
|
*/
|
||||||
|
tables?: SQLiteDBTableSchema[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates the schema to the latest version.
|
||||||
|
*
|
||||||
|
* Called when installing and upgrading the schema, after creating the defined tables.
|
||||||
|
*
|
||||||
|
* @param db The affected DB.
|
||||||
|
* @param oldVersion Old version of the schema or 0 if not installed.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
migrate?(db: SQLiteDB, oldVersion: number): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* @description
|
* @description
|
||||||
|
@ -71,12 +102,33 @@ export class CoreAppProvider {
|
||||||
protected mainMenuOpen: number;
|
protected mainMenuOpen: number;
|
||||||
protected forceOffline = false;
|
protected forceOffline = false;
|
||||||
|
|
||||||
|
// Variables for DB.
|
||||||
|
protected createVersionsTableReady: Promise<any>;
|
||||||
|
protected SCHEMA_VERSIONS_TABLE = 'schema_versions';
|
||||||
|
protected versionsTableSchema: SQLiteDBTableSchema = {
|
||||||
|
name: this.SCHEMA_VERSIONS_TABLE,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'TEXT',
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'version',
|
||||||
|
type: 'INTEGER'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, private appCtrl: App,
|
constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, private appCtrl: App,
|
||||||
private network: Network, logger: CoreLoggerProvider, private events: CoreEventsProvider, zone: NgZone,
|
private network: Network, logger: CoreLoggerProvider, private events: CoreEventsProvider, zone: NgZone,
|
||||||
private menuCtrl: MenuController, private statusBar: StatusBar) {
|
private menuCtrl: MenuController, private statusBar: StatusBar) {
|
||||||
this.logger = logger.getInstance('CoreAppProvider');
|
this.logger = logger.getInstance('CoreAppProvider');
|
||||||
this.db = dbProvider.getDB(this.DBNAME);
|
this.db = dbProvider.getDB(this.DBNAME);
|
||||||
|
|
||||||
|
// Create the schema versions table.
|
||||||
|
this.createVersionsTableReady = this.db.createTableFromSchema(this.versionsTableSchema);
|
||||||
|
|
||||||
this.keyboard.onKeyboardShow().subscribe((data) => {
|
this.keyboard.onKeyboardShow().subscribe((data) => {
|
||||||
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
// Execute the callback in the Angular zone, so change detection doesn't stop working.
|
||||||
zone.run(() => {
|
zone.run(() => {
|
||||||
|
@ -133,6 +185,47 @@ export class CoreAppProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install and upgrade a certain schema.
|
||||||
|
*
|
||||||
|
* @param schema The schema to create.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async createTablesFromSchema(schema: CoreAppSchema): Promise<any> {
|
||||||
|
this.logger.debug(`Apply schema to app DB: ${schema.name}`);
|
||||||
|
|
||||||
|
let oldVersion;
|
||||||
|
|
||||||
|
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(this.SCHEMA_VERSIONS_TABLE, {name: schema.name});
|
||||||
|
oldVersion = entry.version;
|
||||||
|
} catch (error) {
|
||||||
|
// No installed version yet.
|
||||||
|
oldVersion = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVersion >= schema.version) {
|
||||||
|
// Version already installed, nothing else to do.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.debug(`Migrating schema '${schema.name}' of app DB from version ${oldVersion} to ${schema.version}`);
|
||||||
|
|
||||||
|
if (schema.tables) {
|
||||||
|
await this.db.createTablesFromSchema(schema.tables);
|
||||||
|
}
|
||||||
|
if (schema.migrate) {
|
||||||
|
await schema.migrate(this.db, oldVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set installed version.
|
||||||
|
await this.db.insertRecord(this.SCHEMA_VERSIONS_TABLE, {name: schema.name, version: schema.version});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the application global database.
|
* Get the application global database.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreAppProvider } from './app';
|
import { CoreAppProvider, CoreAppSchema } from './app';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory to provide access to dynamic and permanent config and settings.
|
* Factory to provide access to dynamic and permanent config and settings.
|
||||||
|
@ -24,7 +24,11 @@ import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
export class CoreConfigProvider {
|
export class CoreConfigProvider {
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
protected TABLE_NAME = 'core_config';
|
protected TABLE_NAME = 'core_config';
|
||||||
protected tableSchema: SQLiteDBTableSchema = {
|
protected tableSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreConfigProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
name: this.TABLE_NAME,
|
name: this.TABLE_NAME,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
@ -37,11 +41,17 @@ export class CoreConfigProvider {
|
||||||
name: 'value'
|
name: 'value'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
|
|
||||||
constructor(appProvider: CoreAppProvider) {
|
constructor(appProvider: CoreAppProvider) {
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTableFromSchema(this.tableSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.tableSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +60,9 @@ export class CoreConfigProvider {
|
||||||
* @param name The config name.
|
* @param name The config name.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
delete(name: string): Promise<any> {
|
async delete(name: string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.TABLE_NAME, { name: name });
|
return this.appDB.deleteRecords(this.TABLE_NAME, { name: name });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,16 +73,20 @@ export class CoreConfigProvider {
|
||||||
* @param defaultValue Default value to use if the entry is not found.
|
* @param defaultValue Default value to use if the entry is not found.
|
||||||
* @return Resolves upon success along with the config data. Reject on failure.
|
* @return Resolves upon success along with the config data. Reject on failure.
|
||||||
*/
|
*/
|
||||||
get(name: string, defaultValue?: any): Promise<any> {
|
async get(name: string, defaultValue?: any): Promise<any> {
|
||||||
return this.appDB.getRecord(this.TABLE_NAME, { name: name }).then((entry) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const entry = await this.appDB.getRecord(this.TABLE_NAME, { name: name });
|
||||||
|
|
||||||
return entry.value;
|
return entry.value;
|
||||||
}).catch((error) => {
|
} catch (error) {
|
||||||
if (typeof defaultValue != 'undefined') {
|
if (typeof defaultValue != 'undefined') {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
throw error;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +96,9 @@ export class CoreConfigProvider {
|
||||||
* @param value The config value. Can only store number or strings.
|
* @param value The config value. Can only store number or strings.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
set(name: string, value: number | string): Promise<any> {
|
async set(name: string, value: number | string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.insertRecord(this.TABLE_NAME, { name: name, value: value });
|
return this.appDB.insertRecord(this.TABLE_NAME, { name: name, value: value });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
|
|
||||||
import { Injectable, NgZone } from '@angular/core';
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
import { Network } from '@ionic-native/network';
|
import { Network } from '@ionic-native/network';
|
||||||
import { CoreAppProvider } from './app';
|
import { CoreAppProvider, CoreAppSchema } from './app';
|
||||||
import { CoreConfigProvider } from './config';
|
import { CoreConfigProvider } from './config';
|
||||||
import { CoreLoggerProvider } from './logger';
|
import { CoreLoggerProvider } from './logger';
|
||||||
import { CoreUtilsProvider } from './utils/utils';
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface that all cron handlers must implement.
|
* Interface that all cron handlers must implement.
|
||||||
|
@ -92,7 +92,11 @@ export class CoreCronDelegate {
|
||||||
|
|
||||||
// Variables for database.
|
// Variables for database.
|
||||||
protected CRON_TABLE = 'cron';
|
protected CRON_TABLE = 'cron';
|
||||||
protected tableSchema: SQLiteDBTableSchema = {
|
protected tableSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreCronDelegate',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
name: this.CRON_TABLE,
|
name: this.CRON_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
@ -105,10 +109,13 @@ export class CoreCronDelegate {
|
||||||
type: 'INTEGER'
|
type: 'INTEGER'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
protected handlers: { [s: string]: CoreCronHandler } = {};
|
protected handlers: { [s: string]: CoreCronHandler } = {};
|
||||||
protected queuePromise = Promise.resolve();
|
protected queuePromise = Promise.resolve();
|
||||||
|
|
||||||
|
@ -117,7 +124,9 @@ export class CoreCronDelegate {
|
||||||
this.logger = logger.getInstance('CoreCronDelegate');
|
this.logger = logger.getInstance('CoreCronDelegate');
|
||||||
|
|
||||||
this.appDB = this.appProvider.getDB();
|
this.appDB = this.appProvider.getDB();
|
||||||
this.appDB.createTableFromSchema(this.tableSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.tableSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
|
||||||
// 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.onConnect().subscribe(() => {
|
network.onConnect().subscribe(() => {
|
||||||
|
@ -306,16 +315,19 @@ export class CoreCronDelegate {
|
||||||
* @param name Handler's name.
|
* @param name Handler's name.
|
||||||
* @return Promise resolved with the handler's last execution time.
|
* @return Promise resolved with the handler's last execution time.
|
||||||
*/
|
*/
|
||||||
protected getHandlerLastExecutionTime(name: string): Promise<number> {
|
protected async getHandlerLastExecutionTime(name: string): Promise<number> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const id = this.getHandlerLastExecutionId(name);
|
const id = this.getHandlerLastExecutionId(name);
|
||||||
|
|
||||||
return this.appDB.getRecord(this.CRON_TABLE, { id: id }).then((entry) => {
|
try {
|
||||||
|
const entry = await this.appDB.getRecord(this.CRON_TABLE, { id: id });
|
||||||
const time = parseInt(entry.value, 10);
|
const time = parseInt(entry.value, 10);
|
||||||
|
|
||||||
return isNaN(time) ? 0 : time;
|
return isNaN(time) ? 0 : time;
|
||||||
}).catch(() => {
|
} catch (err) {
|
||||||
return 0; // Not set, return 0.
|
return 0; // Not set, return 0.
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -471,7 +483,9 @@ export class CoreCronDelegate {
|
||||||
* @param time Time to set.
|
* @param time Time to set.
|
||||||
* @return Promise resolved when the execution time is saved.
|
* @return Promise resolved when the execution time is saved.
|
||||||
*/
|
*/
|
||||||
protected setHandlerLastExecutionTime(name: string, time: number): Promise<any> {
|
protected async setHandlerLastExecutionTime(name: string, time: number): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const id = this.getHandlerLastExecutionId(name),
|
const id = this.getHandlerLastExecutionId(name),
|
||||||
entry = {
|
entry = {
|
||||||
id: id,
|
id: id,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable, NgZone } from '@angular/core';
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
import { Network } from '@ionic-native/network';
|
import { Network } from '@ionic-native/network';
|
||||||
import { CoreAppProvider } from './app';
|
import { CoreAppProvider, CoreAppSchema } from './app';
|
||||||
import { CoreEventsProvider } from './events';
|
import { CoreEventsProvider } from './events';
|
||||||
import { CoreFileProvider } from './file';
|
import { CoreFileProvider } from './file';
|
||||||
import { CoreInitDelegate } from './init';
|
import { CoreInitDelegate } from './init';
|
||||||
|
@ -28,7 +28,7 @@ import { CoreTextUtilsProvider } from './utils/text';
|
||||||
import { CoreTimeUtilsProvider } from './utils/time';
|
import { CoreTimeUtilsProvider } from './utils/time';
|
||||||
import { CoreUrlUtilsProvider } from './utils/url';
|
import { CoreUrlUtilsProvider } from './utils/url';
|
||||||
import { CoreUtilsProvider } from './utils/utils';
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
|
||||||
|
@ -224,7 +224,10 @@ export class CoreFilepoolProvider {
|
||||||
protected FILES_TABLE = 'filepool_files'; // Downloaded files.
|
protected FILES_TABLE = 'filepool_files'; // Downloaded files.
|
||||||
protected LINKS_TABLE = 'filepool_files_links'; // Links between downloaded files and components.
|
protected LINKS_TABLE = 'filepool_files_links'; // Links between downloaded files and components.
|
||||||
protected PACKAGES_TABLE = 'filepool_packages'; // Downloaded packages (sets of files).
|
protected PACKAGES_TABLE = 'filepool_packages'; // Downloaded packages (sets of files).
|
||||||
protected appTablesSchema: SQLiteDBTableSchema[] = [
|
protected appTablesSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreFilepoolProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
{
|
{
|
||||||
name: this.QUEUE_TABLE,
|
name: this.QUEUE_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -275,7 +278,8 @@ export class CoreFilepoolProvider {
|
||||||
],
|
],
|
||||||
primaryKeys: ['siteId', 'fileId']
|
primaryKeys: ['siteId', 'fileId']
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
};
|
||||||
protected siteSchema: CoreSiteSchema = {
|
protected siteSchema: CoreSiteSchema = {
|
||||||
name: 'CoreFilepoolProvider',
|
name: 'CoreFilepoolProvider',
|
||||||
version: 1,
|
version: 1,
|
||||||
|
@ -392,6 +396,7 @@ export class CoreFilepoolProvider {
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
protected tokenRegex = new RegExp('(\\?|&)token=([A-Za-z0-9]*)');
|
protected tokenRegex = new RegExp('(\\?|&)token=([A-Za-z0-9]*)');
|
||||||
protected queueState: string;
|
protected queueState: string;
|
||||||
protected urlAttributes = [
|
protected urlAttributes = [
|
||||||
|
@ -415,7 +420,9 @@ export class CoreFilepoolProvider {
|
||||||
this.logger = logger.getInstance('CoreFilepoolProvider');
|
this.logger = logger.getInstance('CoreFilepoolProvider');
|
||||||
|
|
||||||
this.appDB = this.appProvider.getDB();
|
this.appDB = this.appProvider.getDB();
|
||||||
this.appDB.createTablesFromSchema(this.appTablesSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.appTablesSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
|
||||||
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
||||||
|
|
||||||
|
@ -567,11 +574,13 @@ export class CoreFilepoolProvider {
|
||||||
* @param link The link to add for the file.
|
* @param link The link to add for the file.
|
||||||
* @return Promise resolved when the file is downloaded.
|
* @return Promise resolved when the file is downloaded.
|
||||||
*/
|
*/
|
||||||
protected addToQueue(siteId: string, fileId: string, url: string, priority: number, revision: number, timemodified: number,
|
protected async addToQueue(siteId: string, fileId: string, url: string, priority: number, revision: number,
|
||||||
filePath: string, onProgress?: (event: any) => any, options: any = {}, link?: any): Promise<any> {
|
timemodified: number, filePath: string, onProgress?: (event: any) => any, options: any = {}, link?: any): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
this.logger.debug(`Adding ${fileId} to the queue`);
|
this.logger.debug(`Adding ${fileId} to the queue`);
|
||||||
|
|
||||||
return this.appDB.insertRecord(this.QUEUE_TABLE, {
|
await this.appDB.insertRecord(this.QUEUE_TABLE, {
|
||||||
siteId: siteId,
|
siteId: siteId,
|
||||||
fileId: fileId,
|
fileId: fileId,
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -583,13 +592,13 @@ export class CoreFilepoolProvider {
|
||||||
repositorytype: options.repositorytype,
|
repositorytype: options.repositorytype,
|
||||||
links: JSON.stringify(link ? [link] : []),
|
links: JSON.stringify(link ? [link] : []),
|
||||||
added: Date.now()
|
added: Date.now()
|
||||||
}).then(() => {
|
});
|
||||||
|
|
||||||
// Check if the queue is running.
|
// Check if the queue is running.
|
||||||
this.checkQueueProcessing();
|
this.checkQueueProcessing();
|
||||||
this.notifyFileDownloading(siteId, fileId);
|
this.notifyFileDownloading(siteId, fileId);
|
||||||
|
|
||||||
return this.getQueuePromise(siteId, fileId, true, onProgress);
|
return this.getQueuePromise(siteId, fileId, true, onProgress);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -608,9 +617,11 @@ export class CoreFilepoolProvider {
|
||||||
* @param alreadyFixed Whether the URL has already been fixed.
|
* @param alreadyFixed Whether the URL has already been fixed.
|
||||||
* @return Resolved on success.
|
* @return Resolved on success.
|
||||||
*/
|
*/
|
||||||
addToQueueByUrl(siteId: string, fileUrl: string, component?: string, componentId?: string | number, timemodified: number = 0,
|
async addToQueueByUrl(siteId: string, fileUrl: string, component?: string, componentId?: string | number,
|
||||||
filePath?: string, onProgress?: (event: any) => any, priority: number = 0, options: any = {}, revision?: number,
|
timemodified: number = 0, filePath?: string, onProgress?: (event: any) => any, priority: number = 0, options: any = {},
|
||||||
alreadyFixed?: boolean): Promise<any> {
|
revision?: number, alreadyFixed?: boolean): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
let fileId,
|
let fileId,
|
||||||
link,
|
link,
|
||||||
queueDeferred;
|
queueDeferred;
|
||||||
|
@ -2309,16 +2320,17 @@ export class CoreFilepoolProvider {
|
||||||
* @param fileUrl The file URL.
|
* @param fileUrl The file URL.
|
||||||
* @return Resolved with file object from DB on success, rejected otherwise.
|
* @return Resolved with file object from DB on success, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
protected hasFileInQueue(siteId: string, fileId: string): Promise<CoreFilepoolQueueEntry> {
|
protected async hasFileInQueue(siteId: string, fileId: string): Promise<CoreFilepoolQueueEntry> {
|
||||||
return this.appDB.getRecord(this.QUEUE_TABLE, { siteId: siteId, fileId: fileId }).then((entry) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const entry = await this.appDB.getRecord(this.QUEUE_TABLE, { siteId: siteId, fileId: fileId });
|
||||||
if (typeof entry === 'undefined') {
|
if (typeof entry === 'undefined') {
|
||||||
return Promise.reject(null);
|
throw null;
|
||||||
}
|
}
|
||||||
// Convert the links to an object.
|
// Convert the links to an object.
|
||||||
entry.links = this.textUtils.parseJSON(entry.links, []);
|
entry.links = this.textUtils.parseJSON(entry.links, []);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2546,19 +2558,25 @@ export class CoreFilepoolProvider {
|
||||||
*
|
*
|
||||||
* @return Resolved on success. Rejected on failure.
|
* @return Resolved on success. Rejected on failure.
|
||||||
*/
|
*/
|
||||||
protected processImportantQueueItem(): Promise<any> {
|
protected async processImportantQueueItem(): Promise<any> {
|
||||||
return this.appDB.getRecords(this.QUEUE_TABLE, undefined, 'priority DESC, added ASC', undefined, 0, 1).then((items) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
let items;
|
||||||
|
|
||||||
|
try {
|
||||||
|
items = await this.appDB.getRecords(this.QUEUE_TABLE, undefined, 'priority DESC, added ASC', undefined, 0, 1);
|
||||||
|
} catch (err) {
|
||||||
|
throw this.ERR_QUEUE_IS_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
const item = items.pop();
|
const item = items.pop();
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return Promise.reject(this.ERR_QUEUE_IS_EMPTY);
|
throw this.ERR_QUEUE_IS_EMPTY;
|
||||||
}
|
}
|
||||||
// Convert the links to an object.
|
// Convert the links to an object.
|
||||||
item.links = this.textUtils.parseJSON(item.links, []);
|
item.links = this.textUtils.parseJSON(item.links, []);
|
||||||
|
|
||||||
return this.processQueueItem(item);
|
return this.processQueueItem(item);
|
||||||
}, () => {
|
|
||||||
return Promise.reject(this.ERR_QUEUE_IS_EMPTY);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2685,7 +2703,9 @@ export class CoreFilepoolProvider {
|
||||||
* @param fileId The file ID.
|
* @param fileId The file ID.
|
||||||
* @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 removeFromQueue(siteId: string, fileId: string): Promise<any> {
|
protected async removeFromQueue(siteId: string, fileId: string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.QUEUE_TABLE, { siteId: siteId, fileId: fileId });
|
return this.appDB.deleteRecords(this.QUEUE_TABLE, { siteId: siteId, fileId: fileId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3003,12 +3023,14 @@ export class CoreFilepoolProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
treatExtensionInQueue(): Promise<any> {
|
async treatExtensionInQueue(): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
this.logger.debug('Treat extensions in queue');
|
this.logger.debug('Treat extensions in queue');
|
||||||
|
|
||||||
return this.appDB.getAllRecords(this.QUEUE_TABLE).then((entries) => {
|
const entries = await this.appDB.getAllRecords(this.QUEUE_TABLE);
|
||||||
const promises = [];
|
|
||||||
entries.forEach((entry) => {
|
return Promise.all(entries.map((entry) => {
|
||||||
|
|
||||||
// For files in the queue, we only need to remove the extension from the fileId.
|
// For files in the queue, we only need to remove the extension from the fileId.
|
||||||
// After downloading, additional info will be added.
|
// After downloading, additional info will be added.
|
||||||
|
@ -3019,11 +3041,8 @@ export class CoreFilepoolProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
promises.push(this.appDB.updateRecords(this.QUEUE_TABLE, { fileId: entry.fileId }, { fileId: fileId }));
|
return this.appDB.updateRecords(this.QUEUE_TABLE, { fileId: entry.fileId }, { fileId: fileId });
|
||||||
});
|
}));
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,13 +17,13 @@ import { Platform, Alert, AlertController } from 'ionic-angular';
|
||||||
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications';
|
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications';
|
||||||
import { Push } from '@ionic-native/push';
|
import { Push } from '@ionic-native/push';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from './app';
|
import { CoreAppProvider, CoreAppSchema } from './app';
|
||||||
import { CoreConfigProvider } from './config';
|
import { CoreConfigProvider } from './config';
|
||||||
import { CoreEventsProvider } from './events';
|
import { CoreEventsProvider } from './events';
|
||||||
import { CoreLoggerProvider } from './logger';
|
import { CoreLoggerProvider } from './logger';
|
||||||
import { CoreTextUtilsProvider } from './utils/text';
|
import { CoreTextUtilsProvider } from './utils/text';
|
||||||
import { CoreUtilsProvider } from './utils/utils';
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreConfigConstants } from '../configconstants';
|
import { CoreConfigConstants } from '../configconstants';
|
||||||
import { Subject, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
|
@ -40,7 +40,10 @@ export class CoreLocalNotificationsProvider {
|
||||||
protected SITES_TABLE = 'notification_sites'; // Store to asigne unique codes to each site.
|
protected SITES_TABLE = 'notification_sites'; // Store to asigne unique codes to each site.
|
||||||
protected COMPONENTS_TABLE = 'notification_components'; // Store to asigne unique codes to each component.
|
protected COMPONENTS_TABLE = 'notification_components'; // Store to asigne unique codes to each component.
|
||||||
protected TRIGGERED_TABLE = 'notifications_triggered'; // Store to prevent re-triggering notifications.
|
protected TRIGGERED_TABLE = 'notifications_triggered'; // Store to prevent re-triggering notifications.
|
||||||
protected tablesSchema: SQLiteDBTableSchema[] = [
|
protected tablesSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreLocalNotificationsProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
{
|
{
|
||||||
name: this.SITES_TABLE,
|
name: this.SITES_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -86,10 +89,12 @@ export class CoreLocalNotificationsProvider {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
};
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
protected codes: { [s: string]: number } = {};
|
protected codes: { [s: string]: number } = {};
|
||||||
protected codeRequestsQueue = {};
|
protected codeRequestsQueue = {};
|
||||||
protected observables = {};
|
protected observables = {};
|
||||||
|
@ -114,7 +119,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
|
|
||||||
this.logger = logger.getInstance('CoreLocalNotificationsProvider');
|
this.logger = logger.getInstance('CoreLocalNotificationsProvider');
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTablesFromSchema(this.tablesSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.tablesSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
|
||||||
platform.ready().then(() => {
|
platform.ready().then(() => {
|
||||||
// Listen to events.
|
// Listen to events.
|
||||||
|
@ -242,34 +249,35 @@ export class CoreLocalNotificationsProvider {
|
||||||
* @param id ID of the element to get its code.
|
* @param id ID of the element to get its code.
|
||||||
* @return Promise resolved when the code is retrieved.
|
* @return Promise resolved when the code is retrieved.
|
||||||
*/
|
*/
|
||||||
protected 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.
|
||||||
if (typeof this.codes[key] != 'undefined') {
|
if (typeof this.codes[key] != 'undefined') {
|
||||||
return Promise.resolve(this.codes[key]);
|
return this.codes[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// Check if we already have a code stored for that ID.
|
// Check if we already have a code stored for that ID.
|
||||||
return this.appDB.getRecord(table, { id: id }).then((entry) => {
|
const entry = await this.appDB.getRecord(table, { id: id });
|
||||||
this.codes[key] = entry.code;
|
this.codes[key] = entry.code;
|
||||||
|
|
||||||
return entry.code;
|
return entry.code;
|
||||||
}).catch(() => {
|
} 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.
|
||||||
return this.appDB.getRecords(table, undefined, 'code DESC').then((entries) => {
|
const entries = await this.appDB.getRecords(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.appDB.insertRecord(table, { id: id, code: newCode }).then(() => {
|
await this.appDB.insertRecord(table, { id: id, code: newCode });
|
||||||
this.codes[key] = newCode;
|
this.codes[key] = newCode;
|
||||||
|
|
||||||
return newCode;
|
return newCode;
|
||||||
});
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,8 +360,11 @@ export class CoreLocalNotificationsProvider {
|
||||||
* @param notification Notification to check.
|
* @param notification Notification to check.
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
isTriggered(notification: ILocalNotification): Promise<any> {
|
async isTriggered(notification: ILocalNotification): Promise<boolean> {
|
||||||
return this.appDB.getRecord(this.TRIGGERED_TABLE, { id: notification.id }).then((stored) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stored = await this.appDB.getRecord(this.TRIGGERED_TABLE, { id: notification.id });
|
||||||
let triggered = (notification.trigger && notification.trigger.at) || 0;
|
let triggered = (notification.trigger && notification.trigger.at) || 0;
|
||||||
|
|
||||||
if (typeof triggered != 'number') {
|
if (typeof triggered != 'number') {
|
||||||
|
@ -361,9 +372,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
return stored.at === triggered;
|
return stored.at === triggered;
|
||||||
}).catch(() => {
|
} catch (err) {
|
||||||
return this.localNotifications.isTriggered(notification.id);
|
return this.localNotifications.isTriggered(notification.id);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -477,7 +488,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
* @param id Notification ID.
|
* @param id Notification ID.
|
||||||
* @return Promise resolved when it is removed.
|
* @return Promise resolved when it is removed.
|
||||||
*/
|
*/
|
||||||
removeTriggered(id: number): Promise<any> {
|
async removeTriggered(id: number): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.TRIGGERED_TABLE, { id: id });
|
return this.appDB.deleteRecords(this.TRIGGERED_TABLE, { id: id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,7 +727,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
* @param notification Triggered notification.
|
* @param notification Triggered notification.
|
||||||
* @return Promise resolved when stored, rejected otherwise.
|
* @return Promise resolved when stored, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
trigger(notification: ILocalNotification): Promise<any> {
|
async trigger(notification: ILocalNotification): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
id: notification.id,
|
id: notification.id,
|
||||||
at: notification.trigger && notification.trigger.at ? notification.trigger.at : Date.now()
|
at: notification.trigger && notification.trigger.at ? notification.trigger.at : Date.now()
|
||||||
|
@ -730,7 +745,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
* @param newName The new name.
|
* @param newName The new name.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
updateComponentName(oldName: string, newName: string): Promise<any> {
|
async updateComponentName(oldName: string, newName: string): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const oldId = this.COMPONENTS_TABLE + '#' + oldName,
|
const oldId = this.COMPONENTS_TABLE + '#' + oldName,
|
||||||
newId = this.COMPONENTS_TABLE + '#' + newName;
|
newId = this.COMPONENTS_TABLE + '#' + newName;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Injectable, Injector } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreAppProvider } from './app';
|
import { CoreAppProvider, CoreAppSchema } from './app';
|
||||||
import { CoreEventsProvider } from './events';
|
import { CoreEventsProvider } from './events';
|
||||||
import { CoreLoggerProvider } from './logger';
|
import { CoreLoggerProvider } from './logger';
|
||||||
import { CoreSitesFactoryProvider } from './sites-factory';
|
import { CoreSitesFactoryProvider } from './sites-factory';
|
||||||
|
@ -170,7 +170,7 @@ export const enum CoreSitesReadingStrategy {
|
||||||
* their own database tables. Example:
|
* their own database tables. Example:
|
||||||
*
|
*
|
||||||
* constructor(sitesProvider: CoreSitesProvider) {
|
* constructor(sitesProvider: CoreSitesProvider) {
|
||||||
* this.sitesProvider.createTableFromSchema(this.tableSchema);
|
* this.sitesProvider.registerSiteSchema(this.siteSchema);
|
||||||
*
|
*
|
||||||
* This provider will automatically create the tables in the databases of all the instantiated sites, and also to the
|
* This provider will automatically create the tables in the databases of all the instantiated sites, and also to the
|
||||||
* databases of sites instantiated from now on.
|
* databases of sites instantiated from now on.
|
||||||
|
@ -181,7 +181,10 @@ export class CoreSitesProvider {
|
||||||
protected SITES_TABLE = 'sites';
|
protected SITES_TABLE = 'sites';
|
||||||
protected CURRENT_SITE_TABLE = 'current_site';
|
protected CURRENT_SITE_TABLE = 'current_site';
|
||||||
protected SCHEMA_VERSIONS_TABLE = 'schema_versions';
|
protected SCHEMA_VERSIONS_TABLE = 'schema_versions';
|
||||||
protected appTablesSchema: SQLiteDBTableSchema[] = [
|
protected appTablesSchema: CoreAppSchema = {
|
||||||
|
name: 'CoreSitesProvider',
|
||||||
|
version: 1,
|
||||||
|
tables: [
|
||||||
{
|
{
|
||||||
name: this.SITES_TABLE,
|
name: this.SITES_TABLE,
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -233,7 +236,8 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
};
|
||||||
|
|
||||||
// Constants to validate a site version.
|
// Constants to validate a site version.
|
||||||
protected WORKPLACE_APP = 3;
|
protected WORKPLACE_APP = 3;
|
||||||
|
@ -249,6 +253,7 @@ export class CoreSitesProvider {
|
||||||
protected currentSite: CoreSite;
|
protected currentSite: CoreSite;
|
||||||
protected sites: { [s: string]: CoreSite } = {};
|
protected sites: { [s: string]: CoreSite } = {};
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
|
protected dbReady: Promise<any>; // Promise resolved when the app DB is initialized.
|
||||||
protected siteSchemasMigration: { [siteId: string]: Promise<any> } = {};
|
protected siteSchemasMigration: { [siteId: string]: Promise<any> } = {};
|
||||||
|
|
||||||
// Schemas for site tables. Other providers can add schemas in here.
|
// Schemas for site tables. Other providers can add schemas in here.
|
||||||
|
@ -323,7 +328,9 @@ export class CoreSitesProvider {
|
||||||
this.logger = logger.getInstance('CoreSitesProvider');
|
this.logger = logger.getInstance('CoreSitesProvider');
|
||||||
|
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTablesFromSchema(this.appTablesSchema);
|
this.dbReady = appProvider.createTablesFromSchema(this.appTablesSchema).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
this.registerSiteSchema(this.siteSchema);
|
this.registerSiteSchema(this.siteSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +866,9 @@ export class CoreSitesProvider {
|
||||||
* @param config Site config (from tool_mobile_get_config).
|
* @param config Site config (from tool_mobile_get_config).
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
addSite(id: string, siteUrl: string, token: string, info: any, privateToken: string = '', config?: any): Promise<any> {
|
async addSite(id: string, siteUrl: string, token: string, info: any, privateToken: string = '', config?: any): Promise<any> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
id: id,
|
id: id,
|
||||||
siteUrl: siteUrl,
|
siteUrl: siteUrl,
|
||||||
|
@ -1070,29 +1079,32 @@ export class CoreSitesProvider {
|
||||||
* @param siteId ID of the site to delete.
|
* @param siteId ID of the site to delete.
|
||||||
* @return Promise to be resolved when the site is deleted.
|
* @return Promise to be resolved when the site is deleted.
|
||||||
*/
|
*/
|
||||||
deleteSite(siteId: string): Promise<any> {
|
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) {
|
||||||
this.logout();
|
this.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getSite(siteId).then((site: CoreSite) => {
|
const site = await this.getSite(siteId);
|
||||||
return site.deleteDB().then(() => {
|
|
||||||
|
await site.deleteDB();
|
||||||
|
|
||||||
// Site DB deleted, now delete the app from the list of sites.
|
// Site DB deleted, now delete the app from the list of sites.
|
||||||
delete this.sites[siteId];
|
delete this.sites[siteId];
|
||||||
|
|
||||||
return this.appDB.deleteRecords(this.SITES_TABLE, { id: siteId }).then(() => {
|
try {
|
||||||
// Site deleted from sites list, now delete the folder.
|
await this.appDB.deleteRecords(this.SITES_TABLE, { id: siteId });
|
||||||
return site.deleteFolder();
|
} 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.
|
||||||
return site.deleteFolder();
|
}
|
||||||
}).then(() => {
|
|
||||||
|
// Site deleted from sites list, now delete the folder.
|
||||||
|
await site.deleteFolder();
|
||||||
|
|
||||||
this.eventsProvider.trigger(CoreEventsProvider.SITE_DELETED, site, siteId);
|
this.eventsProvider.trigger(CoreEventsProvider.SITE_DELETED, site, siteId);
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1100,10 +1112,12 @@ 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.
|
||||||
*/
|
*/
|
||||||
hasSites(): Promise<boolean> {
|
async hasSites(): Promise<boolean> {
|
||||||
return this.appDB.countRecords(this.SITES_TABLE).then((count) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const count = await this.appDB.countRecords(this.SITES_TABLE);
|
||||||
|
|
||||||
return count > 0;
|
return count > 0;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1112,18 +1126,24 @@ export class CoreSitesProvider {
|
||||||
* @param siteId The site ID. If not defined, current site (if available).
|
* @param siteId The site ID. If not defined, current site (if available).
|
||||||
* @return Promise resolved with the site.
|
* @return Promise resolved with the site.
|
||||||
*/
|
*/
|
||||||
getSite(siteId?: string): Promise<CoreSite> {
|
async getSite(siteId?: string): Promise<CoreSite> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
if (!siteId) {
|
if (!siteId) {
|
||||||
return this.currentSite ? Promise.resolve(this.currentSite) : Promise.reject(null);
|
if (this.currentSite) {
|
||||||
|
return this.currentSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw null;
|
||||||
} else if (this.currentSite && this.currentSite.getId() == siteId) {
|
} else if (this.currentSite && this.currentSite.getId() == siteId) {
|
||||||
return Promise.resolve(this.currentSite);
|
return this.currentSite;
|
||||||
} else if (typeof this.sites[siteId] != 'undefined') {
|
} else if (typeof this.sites[siteId] != 'undefined') {
|
||||||
return Promise.resolve(this.sites[siteId]);
|
return this.sites[siteId];
|
||||||
} else {
|
} else {
|
||||||
// Retrieve and create the site.
|
// Retrieve and create the site.
|
||||||
return this.appDB.getRecord(this.SITES_TABLE, { id: siteId }).then((data) => {
|
const data = await this.appDB.getRecord(this.SITES_TABLE, { id: siteId });
|
||||||
|
|
||||||
return this.makeSiteFromSiteListEntry(data);
|
return this.makeSiteFromSiteListEntry(data);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1199,8 +1219,11 @@ export class CoreSitesProvider {
|
||||||
* @param ids IDs of the sites to get. If not defined, return all sites.
|
* @param ids IDs of the sites to get. If not defined, return all sites.
|
||||||
* @return Promise resolved when the sites are retrieved.
|
* @return Promise resolved when the sites are retrieved.
|
||||||
*/
|
*/
|
||||||
getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> {
|
async getSites(ids?: string[]): Promise<CoreSiteBasicInfo[]> {
|
||||||
return this.appDB.getAllRecords(this.SITES_TABLE).then((sites) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const sites = await this.appDB.getAllRecords(this.SITES_TABLE);
|
||||||
|
|
||||||
const formattedSites = [];
|
const formattedSites = [];
|
||||||
sites.forEach((site) => {
|
sites.forEach((site) => {
|
||||||
if (!ids || ids.indexOf(site.id) > -1) {
|
if (!ids || ids.indexOf(site.id) > -1) {
|
||||||
|
@ -1219,7 +1242,6 @@ export class CoreSitesProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
return formattedSites;
|
return formattedSites;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1257,12 +1279,14 @@ export class CoreSitesProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved when the sites IDs are retrieved.
|
* @return Promise resolved when the sites IDs are retrieved.
|
||||||
*/
|
*/
|
||||||
getLoggedInSitesIds(): Promise<string[]> {
|
async getLoggedInSitesIds(): Promise<string[]> {
|
||||||
return this.appDB.getRecords(this.SITES_TABLE, {loggedOut : 0}).then((sites) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const sites = await this.appDB.getRecords(this.SITES_TABLE, {loggedOut : 0});
|
||||||
|
|
||||||
return sites.map((site) => {
|
return sites.map((site) => {
|
||||||
return site.id;
|
return site.id;
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1270,12 +1294,14 @@ export class CoreSitesProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved when the sites IDs are retrieved.
|
* @return Promise resolved when the sites IDs are retrieved.
|
||||||
*/
|
*/
|
||||||
getSitesIds(): Promise<string[]> {
|
async getSitesIds(): Promise<string[]> {
|
||||||
return this.appDB.getAllRecords(this.SITES_TABLE).then((sites) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const sites = await this.appDB.getAllRecords(this.SITES_TABLE);
|
||||||
|
|
||||||
return sites.map((site) => {
|
return sites.map((site) => {
|
||||||
return site.id;
|
return site.id;
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1284,15 +1310,17 @@ export class CoreSitesProvider {
|
||||||
* @param siteid ID of the site the user is accessing.
|
* @param siteid ID of the site the user is accessing.
|
||||||
* @return Promise resolved when current site is stored.
|
* @return Promise resolved when current site is stored.
|
||||||
*/
|
*/
|
||||||
login(siteId: string): Promise<void> {
|
async login(siteId: string): Promise<void> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
id: 1,
|
id: 1,
|
||||||
siteId: siteId
|
siteId: siteId
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.appDB.insertRecord(this.CURRENT_SITE_TABLE, entry).then(() => {
|
await this.appDB.insertRecord(this.CURRENT_SITE_TABLE, entry);
|
||||||
|
|
||||||
this.eventsProvider.trigger(CoreEventsProvider.LOGIN, {}, siteId);
|
this.eventsProvider.trigger(CoreEventsProvider.LOGIN, {}, siteId);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1300,7 +1328,9 @@ export class CoreSitesProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved when the user is logged out.
|
* @return Promise resolved when the user is logged out.
|
||||||
*/
|
*/
|
||||||
logout(): Promise<any> {
|
async logout(): Promise<void> {
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
let siteId;
|
let siteId;
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
|
@ -1317,9 +1347,11 @@ export class CoreSitesProvider {
|
||||||
promises.push(this.appDB.deleteRecords(this.CURRENT_SITE_TABLE, { id: 1 }));
|
promises.push(this.appDB.deleteRecords(this.CURRENT_SITE_TABLE, { id: 1 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).finally(() => {
|
try {
|
||||||
|
await Promise.all(promises);
|
||||||
|
} finally {
|
||||||
this.eventsProvider.trigger(CoreEventsProvider.LOGOUT, {}, siteId);
|
this.eventsProvider.trigger(CoreEventsProvider.LOGOUT, {}, siteId);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1327,21 +1359,24 @@ export class CoreSitesProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved if a session is restored.
|
* @return Promise resolved if a session is restored.
|
||||||
*/
|
*/
|
||||||
restoreSession(): Promise<any> {
|
async restoreSession(): Promise<any> {
|
||||||
if (this.sessionRestored) {
|
if (this.sessionRestored) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.dbReady;
|
||||||
|
|
||||||
this.sessionRestored = true;
|
this.sessionRestored = true;
|
||||||
|
|
||||||
return this.appDB.getRecord(this.CURRENT_SITE_TABLE, { id: 1 }).then((currentSite) => {
|
try {
|
||||||
|
const currentSite = await this.appDB.getRecord(this.CURRENT_SITE_TABLE, { 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}`);
|
||||||
|
|
||||||
return this.loadSite(siteId);
|
return this.loadSite(siteId);
|
||||||
}).catch(() => {
|
} catch (err) {
|
||||||
// No current session.
|
// No current session.
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1351,8 +1386,10 @@ export class CoreSitesProvider {
|
||||||
* @param loggedOut True to set the site as logged out, false otherwise.
|
* @param loggedOut True to set the site as logged out, false otherwise.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
setSiteLoggedOut(siteId: string, loggedOut: boolean): Promise<any> {
|
async setSiteLoggedOut(siteId: string, loggedOut: boolean): Promise<any> {
|
||||||
return this.getSite(siteId).then((site) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const site = await this.getSite(siteId);
|
||||||
const newValues = {
|
const newValues = {
|
||||||
token: '', // Erase the token for security.
|
token: '', // Erase the token for security.
|
||||||
loggedOut: loggedOut ? 1 : 0
|
loggedOut: loggedOut ? 1 : 0
|
||||||
|
@ -1361,7 +1398,6 @@ export class CoreSitesProvider {
|
||||||
site.setLoggedOut(loggedOut);
|
site.setLoggedOut(loggedOut);
|
||||||
|
|
||||||
return this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId });
|
return this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1396,8 +1432,10 @@ export class CoreSitesProvider {
|
||||||
* @param privateToken User's private token.
|
* @param privateToken User's private token.
|
||||||
* @return A promise resolved when the site is updated.
|
* @return A promise resolved when the site is updated.
|
||||||
*/
|
*/
|
||||||
updateSiteTokenBySiteId(siteId: string, token: string, privateToken: string = ''): Promise<any> {
|
async updateSiteTokenBySiteId(siteId: string, token: string, privateToken: string = ''): Promise<any> {
|
||||||
return this.getSite(siteId).then((site) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const site = await this.getSite(siteId);
|
||||||
const newValues = {
|
const newValues = {
|
||||||
token: token,
|
token: token,
|
||||||
privateToken: privateToken,
|
privateToken: privateToken,
|
||||||
|
@ -1409,7 +1447,6 @@ export class CoreSitesProvider {
|
||||||
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.
|
||||||
|
|
||||||
return this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId });
|
return this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1418,9 +1455,14 @@ export class CoreSitesProvider {
|
||||||
* @param siteid Site's ID.
|
* @param siteid Site's ID.
|
||||||
* @return A promise resolved when the site is updated.
|
* @return A promise resolved when the site is updated.
|
||||||
*/
|
*/
|
||||||
updateSiteInfo(siteId: string): Promise<any> {
|
async updateSiteInfo(siteId: string): Promise<any> {
|
||||||
return this.getSite(siteId).then((site) => {
|
await this.dbReady;
|
||||||
return site.fetchSiteInfo().then((info) => {
|
|
||||||
|
const site = await this.getSite(siteId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const info = await site.fetchSiteInfo();
|
||||||
site.setInfo(info);
|
site.setInfo(info);
|
||||||
|
|
||||||
const versionCheck = this.isValidMoodleVersion(info);
|
const versionCheck = this.isValidMoodleVersion(info);
|
||||||
|
@ -1430,9 +1472,14 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get the site config.
|
// Try to get the site config.
|
||||||
return this.getSiteConfig(site).catch(() => {
|
let config;
|
||||||
|
|
||||||
|
try {
|
||||||
|
config = await this.getSiteConfig(site);
|
||||||
|
} catch (error) {
|
||||||
// Error getting config, keep the current one.
|
// Error getting config, keep the current one.
|
||||||
}).then((config) => {
|
}
|
||||||
|
|
||||||
const newValues: any = {
|
const newValues: any = {
|
||||||
info: JSON.stringify(info),
|
info: JSON.stringify(info),
|
||||||
loggedOut: site.isLoggedOut() ? 1 : 0
|
loggedOut: site.isLoggedOut() ? 1 : 0
|
||||||
|
@ -1443,14 +1490,14 @@ export class CoreSitesProvider {
|
||||||
newValues.config = JSON.stringify(config);
|
newValues.config = JSON.stringify(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId }).finally(() => {
|
try {
|
||||||
|
await this.appDB.updateRecords(this.SITES_TABLE, newValues, { id: siteId });
|
||||||
|
} finally {
|
||||||
this.eventsProvider.trigger(CoreEventsProvider.SITE_UPDATED, info, siteId);
|
this.eventsProvider.trigger(CoreEventsProvider.SITE_UPDATED, info, siteId);
|
||||||
});
|
}
|
||||||
});
|
} catch (error) {
|
||||||
}).catch((error) => {
|
|
||||||
// Ignore that we cannot fetch site info. Probably the auth token is invalid.
|
// Ignore that we cannot fetch site info. Probably the auth token is invalid.
|
||||||
});
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1476,11 +1523,13 @@ export class CoreSitesProvider {
|
||||||
* @param username If set, it will return only the sites where the current user has this username.
|
* @param username If set, it will return only the sites where the current user has this username.
|
||||||
* @return Promise resolved with the site IDs (array).
|
* @return Promise resolved with the site IDs (array).
|
||||||
*/
|
*/
|
||||||
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) {
|
||||||
return Promise.resolve([this.currentSite.getId()]);
|
return [this.currentSite.getId()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,18 +1538,19 @@ export class CoreSitesProvider {
|
||||||
// URL doesn't have http(s) protocol. Check if it has any protocol.
|
// URL doesn't have http(s) protocol. Check if it has any protocol.
|
||||||
if (this.urlUtils.isAbsoluteURL(url)) {
|
if (this.urlUtils.isAbsoluteURL(url)) {
|
||||||
// It has some protocol. Return empty array.
|
// It has some protocol. Return empty array.
|
||||||
return Promise.resolve([]);
|
return [];
|
||||||
} else {
|
} else {
|
||||||
// No protocol, probably a relative URL. Return current site.
|
// No protocol, probably a relative URL. Return current site.
|
||||||
if (this.currentSite) {
|
if (this.currentSite) {
|
||||||
return Promise.resolve([this.currentSite.getId()]);
|
return [this.currentSite.getId()];
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve([]);
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.appDB.getAllRecords(this.SITES_TABLE).then((siteEntries) => {
|
try {
|
||||||
|
const siteEntries = await this.appDB.getAllRecords(this.SITES_TABLE);
|
||||||
const ids = [];
|
const ids = [];
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
|
@ -1516,13 +1566,13 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(() => {
|
await Promise.all(promises);
|
||||||
|
|
||||||
return ids;
|
return ids;
|
||||||
});
|
} catch (error) {
|
||||||
}).catch(() => {
|
|
||||||
// Shouldn't happen.
|
// Shouldn't happen.
|
||||||
return [];
|
return [];
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1530,10 +1580,12 @@ export class CoreSitesProvider {
|
||||||
*
|
*
|
||||||
* @return Promise resolved with the site ID.
|
* @return Promise resolved with the site ID.
|
||||||
*/
|
*/
|
||||||
getStoredCurrentSiteId(): Promise<string> {
|
async getStoredCurrentSiteId(): Promise<string> {
|
||||||
return this.appDB.getRecord(this.CURRENT_SITE_TABLE, { id: 1 }).then((currentSite) => {
|
await this.dbReady;
|
||||||
|
|
||||||
|
const currentSite = await this.appDB.getRecord(this.CURRENT_SITE_TABLE, { id: 1 });
|
||||||
|
|
||||||
return currentSite.siteId;
|
return currentSite.siteId;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1580,6 +1632,7 @@ export class CoreSitesProvider {
|
||||||
* Create a table in all the sites databases.
|
* Create a table in all the sites databases.
|
||||||
*
|
*
|
||||||
* @param table Table schema.
|
* @param table Table schema.
|
||||||
|
* @deprecated. Please use registerSiteSchema instead.
|
||||||
*/
|
*/
|
||||||
createTableFromSchema(table: SQLiteDBTableSchema): void {
|
createTableFromSchema(table: SQLiteDBTableSchema): void {
|
||||||
this.createTablesFromSchema([table]);
|
this.createTablesFromSchema([table]);
|
||||||
|
@ -1589,6 +1642,7 @@ export class CoreSitesProvider {
|
||||||
* Create several tables in all the sites databases.
|
* Create several tables in all the sites databases.
|
||||||
*
|
*
|
||||||
* @param tables List of tables schema.
|
* @param tables List of tables schema.
|
||||||
|
* @deprecated. Please use registerSiteSchema instead.
|
||||||
*/
|
*/
|
||||||
createTablesFromSchema(tables: SQLiteDBTableSchema[]): void {
|
createTablesFromSchema(tables: SQLiteDBTableSchema[]): void {
|
||||||
// Add the tables to the list of schemas. This list is to create all the tables in new sites.
|
// Add the tables to the list of schemas. This list is to create all the tables in new sites.
|
||||||
|
|
Loading…
Reference in New Issue