commit
						e8e7099a1c
					
				| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreSite } from '@classes/site'; | ||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| @ -38,95 +38,99 @@ export class AddonCalendarProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static EVENTS_TABLE = 'addon_calendar_events'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonCalendarProvider.EVENTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'id', | ||||
|                     type: 'INTEGER', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'notificationtime', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'description', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'format', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'eventtype', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timestart', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timeduration', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'categoryid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'groupid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'instance', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'modulename', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'repeatid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'visible', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'uuid', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'sequence', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'subscriptionid', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonCalendarProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonCalendarProvider.EVENTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'notificationtime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'description', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'format', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'eventtype', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timestart', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timeduration', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'categoryid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'groupid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'instance', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'modulename', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'repeatid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'visible', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'uuid', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'sequence', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'subscriptionid', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     protected logger; | ||||
| 
 | ||||
| @ -134,7 +138,7 @@ export class AddonCalendarProvider { | ||||
|             private coursesProvider: CoreCoursesProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private localNotificationsProvider: CoreLocalNotificationsProvider, private configProvider: CoreConfigProvider) { | ||||
|         this.logger = logger.getInstance('AddonCalendarProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| 
 | ||||
| @ -29,65 +29,69 @@ export class AddonMessagesOfflineProvider { | ||||
|     // Variables for database.
 | ||||
|     static MESSAGES_TABLE = 'addon_messages_offline_messages'; // When group messaging isn't available or a new conversation starts.
 | ||||
|     static CONVERSATION_MESSAGES_TABLE = 'addon_messages_offline_conversation_messages'; // Conversation messages.
 | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonMessagesOfflineProvider.MESSAGES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'touserid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'useridfrom', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'smallmessage', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'deviceoffline', // If message was stored because device was offline.
 | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['touserid', 'smallmessage', 'timecreated'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonMessagesOfflineProvider.CONVERSATION_MESSAGES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'conversationid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'text', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'deviceoffline', // If message was stored because device was offline.
 | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'conversation', // Data about the conversation.
 | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['conversationid', 'text', 'timecreated'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonMessagesOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonMessagesOfflineProvider.MESSAGES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'touserid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'useridfrom', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'smallmessage', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'deviceoffline', // If message was stored because device was offline.
 | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['touserid', 'smallmessage', 'timecreated'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonMessagesOfflineProvider.CONVERSATION_MESSAGES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'conversationid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'text', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'deviceoffline', // If message was stored because device was offline.
 | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'conversation', // Data about the conversation.
 | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['conversationid', 'text', 'timecreated'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, | ||||
|             private textUtils: CoreTextUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonMessagesOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -15,7 +15,7 @@ | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| 
 | ||||
| @ -30,105 +30,109 @@ export class AddonModAssignOfflineProvider { | ||||
|     // Variables for database.
 | ||||
|     static SUBMISSIONS_TABLE = 'addon_mod_assign_submissions'; | ||||
|     static SUBMISSIONS_GRADES_TABLE = 'addon_mod_assign_submissions_grading'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModAssignOfflineProvider.SUBMISSIONS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'assignid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'plugindata', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'onlinetimemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'submitted', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'submissionstatement', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['assignid', 'userid'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModAssignOfflineProvider.SUBMISSIONS_GRADES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'assignid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'grade', | ||||
|                     type: 'REAL' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attemptnumber', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'addattempt', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'workflowstate', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'applytoall', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'outcomes', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'plugindata', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['assignid', 'userid'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModAssignOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModAssignOfflineProvider.SUBMISSIONS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'assignid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'plugindata', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'onlinetimemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'submitted', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'submissionstatement', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['assignid', 'userid'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModAssignOfflineProvider.SUBMISSIONS_GRADES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'assignid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'grade', | ||||
|                         type: 'REAL' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attemptnumber', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'addattempt', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'workflowstate', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'applytoall', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'outcomes', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'plugindata', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['assignid', 'userid'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider, | ||||
|             private fileProvider: CoreFileProvider, private timeUtils: CoreTimeUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonModAssignOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to handle offline choices. | ||||
| @ -23,45 +23,50 @@ export class AddonModChoiceOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static CHOICE_TABLE = 'addon_mod_choice_responses'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModChoiceOfflineProvider.CHOICE_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'choiceid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'responses', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'deleting', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['choiceid', 'userid'] | ||||
|         } | ||||
|     ]; | ||||
| 
 | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModChoiceOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModChoiceOfflineProvider.CHOICE_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'choiceid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'responses', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'deleting', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['choiceid', 'userid'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private sitesProvider: CoreSitesProvider) { | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,10 +14,11 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to handle Offline data. | ||||
| @ -28,48 +29,67 @@ export class AddonModDataOfflineProvider { | ||||
|     protected logger; | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static DATA_ENTRY_TABLE = 'addon_mod_data_entry'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModDataOfflineProvider.DATA_ENTRY_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'dataid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'groupid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'action', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'entryid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'fields', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['dataid', 'entryid'] | ||||
|     static DATA_ENTRY_TABLE = 'addon_mod_data_entry_1'; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModDataOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModDataOfflineProvider.DATA_ENTRY_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'dataid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'groupid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'action', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'entryid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'fields', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['dataid', 'entryid', 'action'] | ||||
|             } | ||||
|         ], | ||||
|         migrate(db: SQLiteDB, oldVersion: number): Promise<any> | void { | ||||
|             if (oldVersion == 0) { | ||||
|                 // Move the records from the old table.
 | ||||
|                 const newTable = AddonModDataOfflineProvider.DATA_ENTRY_TABLE; | ||||
|                 const oldTable = 'addon_mod_data_entry'; | ||||
| 
 | ||||
|                 return db.tableExists(oldTable).then(() => { | ||||
|                     return db.insertRecordsFrom(newTable, oldTable).then(() => { | ||||
|                         return db.dropTable(oldTable); | ||||
|                     }); | ||||
|                 }).catch(() => { | ||||
|                     // Old table does not exist, ignore.
 | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     ]; | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider, | ||||
|             private fileProvider: CoreFileProvider, private fileUploaderProvider: CoreFileUploaderProvider) { | ||||
|         this.logger = logger.getInstance('AddonModDataOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| 
 | ||||
| @ -28,39 +28,43 @@ export class AddonModFeedbackOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static FEEDBACK_TABLE = 'addon_mod_feedback_answers'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModFeedbackOfflineProvider.FEEDBACK_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'feedbackid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'page', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'responses', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['feedbackid', 'page'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModFeedbackOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModFeedbackOfflineProvider.FEEDBACK_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'feedbackid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'page', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'responses', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['feedbackid', 'page'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, | ||||
|         private textUtils: CoreTextUtilsProvider, private timeUtils: CoreTimeUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonModFeedbackOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| 
 | ||||
| /** | ||||
| @ -27,101 +27,105 @@ export class AddonModForumOfflineProvider { | ||||
|     static DISCUSSIONS_TABLE = 'addon_mod_forum_discussions'; | ||||
|     static REPLIES_TABLE = 'addon_mod_forum_replies'; | ||||
| 
 | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModForumOfflineProvider.DISCUSSIONS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'forumid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'subject', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'message', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'options', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'groupid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER', | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['forumid', 'userid', 'timecreated'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModForumOfflineProvider.REPLIES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'postid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'discussionid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'forumid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'subject', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'message', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'options', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER', | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['postid', 'userid'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModForumOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModForumOfflineProvider.DISCUSSIONS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'forumid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'subject', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'message', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'options', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'groupid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER', | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['forumid', 'userid', 'timecreated'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModForumOfflineProvider.REPLIES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'postid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'discussionid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'forumid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'subject', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'message', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'options', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER', | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['postid', 'userid'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private fileProvider: CoreFileProvider, | ||||
|             private sitesProvider: CoreSitesProvider, | ||||
|             private textUtils: CoreTextUtilsProvider) { | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| 
 | ||||
| @ -27,56 +27,60 @@ export class AddonModGlossaryOfflineProvider { | ||||
|     // Variables for database.
 | ||||
|     static ENTRIES_TABLE = 'addon_mod_glossary_entrues'; | ||||
| 
 | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModGlossaryOfflineProvider.ENTRIES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'glossaryid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'concept', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'definition', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'definitionformat', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'options', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attachments', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['glossaryid', 'concept', 'timecreated'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModGlossaryOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModGlossaryOfflineProvider.ENTRIES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'glossaryid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'concept', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'definition', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'definitionformat', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'options', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attachments', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['glossaryid', 'concept', 'timecreated'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private fileProvider: CoreFileProvider, | ||||
|             private sitesProvider: CoreSitesProvider, | ||||
|             private textUtils: CoreTextUtilsProvider, | ||||
|             private utils: CoreUtilsProvider) { | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| @ -31,103 +31,108 @@ export class AddonModLessonOfflineProvider { | ||||
|     // Variables for database. We use lowercase in the names to match the WS responses.
 | ||||
|     static RETAKES_TABLE = 'addon_mod_lesson_retakes'; | ||||
|     static PAGE_ATTEMPTS_TABLE = 'addon_mod_lesson_page_attempts'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModLessonOfflineProvider.RETAKES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'lessonid', | ||||
|                     type: 'INTEGER', | ||||
|                     primaryKey: true // Only 1 offline retake per lesson.
 | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'retake', // Retake number.
 | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'finished', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'outoftime', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'lastquestionpage', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModLessonOfflineProvider.PAGE_ATTEMPTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'lessonid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'retake', // Retake number.
 | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'pageid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'data', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'type', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'newpageid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'correct', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'answerid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'useranswer', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['lessonid', 'retake', 'pageid', 'timemodified'] // A user can attempt several times per page and retake.
 | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModLessonOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModLessonOfflineProvider.RETAKES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'lessonid', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true // Only 1 offline retake per lesson.
 | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'retake', // Retake number.
 | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'finished', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'outoftime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'lastquestionpage', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModLessonOfflineProvider.PAGE_ATTEMPTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'lessonid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'retake', // Retake number.
 | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'pageid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'data', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'type', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'newpageid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'correct', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'answerid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'useranswer', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                 ], | ||||
|                 // A user can attempt several times per page and retake.
 | ||||
|                 primaryKeys: ['lessonid', 'retake', 'pageid', 'timemodified'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonModLessonOfflineProvider'); | ||||
| 
 | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -17,7 +17,7 @@ import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreEventsProvider } from '@providers/events'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreSyncProvider } from '@providers/sync'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| @ -58,25 +58,31 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static RETAKES_FINISHED_TABLE = 'addon_mod_lesson_retakes_finished_sync'; | ||||
|     protected tablesSchema = { | ||||
|         name: AddonModLessonSyncProvider.RETAKES_FINISHED_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModLessonSyncProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'lessonid', | ||||
|                 type: 'INTEGER', | ||||
|                 primaryKey: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'retake', | ||||
|                 type: 'INTEGER' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'pageid', | ||||
|                 type: 'INTEGER' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'timefinished', | ||||
|                 type: 'INTEGER' | ||||
|                 name: AddonModLessonSyncProvider.RETAKES_FINISHED_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'lessonid', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'retake', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'pageid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timefinished', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -93,7 +99,7 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider { | ||||
| 
 | ||||
|         this.componentTranslate = courseProvider.translateModuleName('lesson'); | ||||
| 
 | ||||
|         this.sitesProvider.createTableFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -15,7 +15,7 @@ | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| @ -155,21 +155,27 @@ export class AddonModLessonProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static PASSWORD_TABLE = 'addon_mod_lesson_password'; | ||||
|     protected tablesSchema = { | ||||
|         name: AddonModLessonProvider.PASSWORD_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModLessonProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'lessonid', | ||||
|                 type: 'INTEGER', | ||||
|                 primaryKey: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'password', | ||||
|                 type: 'TEXT' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'timemodified', | ||||
|                 type: 'INTEGER' | ||||
|                 name: AddonModLessonProvider.PASSWORD_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'lessonid', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'password', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -182,7 +188,7 @@ export class AddonModLessonProvider { | ||||
|             private lessonOfflineProvider: AddonModLessonOfflineProvider) { | ||||
|         this.logger = logger.getInstance('AddonModLessonProvider'); | ||||
| 
 | ||||
|         this.sitesProvider.createTableFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable, Injector } from '@angular/core'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { AddonModQuizAccessRuleHandler } from '../../../providers/access-rules-delegate'; | ||||
| import { AddonModQuizAccessPasswordComponent } from '../component/password'; | ||||
| 
 | ||||
| @ -25,21 +25,27 @@ import { AddonModQuizAccessPasswordComponent } from '../component/password'; | ||||
| export class AddonModQuizAccessPasswordHandler implements AddonModQuizAccessRuleHandler { | ||||
|     // Variables for database.
 | ||||
|     static PASSWORD_TABLE = 'addon_mod_quiz_access_password'; | ||||
|     protected tableSchema = { | ||||
|         name: AddonModQuizAccessPasswordHandler.PASSWORD_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModQuizAccessPasswordHandler', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'id', | ||||
|                 type: 'INTEGER', | ||||
|                 primaryKey: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'password', | ||||
|                 type: 'TEXT' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'timemodified', | ||||
|                 type: 'INTEGER' | ||||
|                 name: AddonModQuizAccessPasswordHandler.PASSWORD_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'password', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -48,7 +54,7 @@ export class AddonModQuizAccessPasswordHandler implements AddonModQuizAccessRule | ||||
|     ruleName = 'quizaccess_password'; | ||||
| 
 | ||||
|     constructor(private sitesProvider: CoreSitesProvider) { | ||||
|         this.sitesProvider.createTableFromSchema(this.tableSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -15,7 +15,7 @@ | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| import { CoreQuestionProvider } from '@core/question/providers/question'; | ||||
| @ -33,57 +33,61 @@ export class AddonModQuizOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static ATTEMPTS_TABLE = 'addon_mod_quiz_attempts'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModQuizOfflineProvider.ATTEMPTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'id', // Attempt ID.
 | ||||
|                     type: 'INTEGER', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attempt', // Attempt number.
 | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'quizid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'currentpage', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'finished', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModQuizOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModQuizOfflineProvider.ATTEMPTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', // Attempt ID.
 | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attempt', // Attempt number.
 | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'quizid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'currentpage', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'finished', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private questionProvider: CoreQuestionProvider, private translate: TranslateService, private utils: CoreUtilsProvider, | ||||
|             private behaviourDelegate: CoreQuestionBehaviourDelegate) { | ||||
|         this.logger = logger.getInstance('AddonModQuizOfflineProvider'); | ||||
| 
 | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreSyncProvider } from '@providers/sync'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| @ -34,95 +34,99 @@ export class AddonModScormOfflineProvider { | ||||
|     // Variables for database.
 | ||||
|     static ATTEMPTS_TABLE = 'addon_mod_scorm_offline_attempts'; | ||||
|     static TRACKS_TABLE = 'addon_mod_scorm_offline_scos_tracks'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModScormOfflineProvider.ATTEMPTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'scormid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attempt', // Attempt number.
 | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'snapshot', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['scormid', 'userid', 'attempt'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModScormOfflineProvider.TRACKS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'scormid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attempt', // Attempt number.
 | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'scoid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'element', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'value', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'synced', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['scormid', 'userid', 'attempt', 'scoid', 'element'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModScormOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModScormOfflineProvider.ATTEMPTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'scormid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attempt', // Attempt number.
 | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'snapshot', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['scormid', 'userid', 'attempt'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModScormOfflineProvider.TRACKS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'scormid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attempt', // Attempt number.
 | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'scoid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'element', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'value', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'synced', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['scormid', 'userid', 'attempt', 'scoid', 'element'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private syncProvider: CoreSyncProvider, private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, | ||||
|             private userProvider: CoreUserProvider) { | ||||
|         this.logger = logger.getInstance('AddonModScormOfflineProvider'); | ||||
| 
 | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| 
 | ||||
| /** | ||||
| @ -27,42 +27,46 @@ export class AddonModSurveyOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static SURVEY_TABLE = 'addon_mod_survey_answers'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModSurveyOfflineProvider.SURVEY_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'surveyid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'answers', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['surveyid', 'userid'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModSurveyOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModSurveyOfflineProvider.SURVEY_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'surveyid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'answers', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['surveyid', 'userid'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonModSurveyOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to handle offline wiki. | ||||
| @ -26,62 +26,66 @@ export class AddonModWikiOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static NEW_PAGES_TABLE = 'addon_mod_wiki_new_pages_store'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModWikiOfflineProvider.NEW_PAGES_TABLE, | ||||
|             columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModWikiOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|                 { | ||||
|                     name: 'wikiid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'subwikiid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'groupid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'title', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'cachedcontent', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'contentformat', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'caneditpage', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['wikiid', 'subwikiid', 'userid', 'groupid', 'title'] | ||||
|         } | ||||
|     ]; | ||||
|                 name: AddonModWikiOfflineProvider.NEW_PAGES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'wikiid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'subwikiid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'groupid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'title', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'cachedcontent', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'contentformat', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'caneditpage', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['wikiid', 'subwikiid', 'userid', 'groupid', 'title'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider) { | ||||
|         this.logger = logger.getInstance('AddonModWikiOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| 
 | ||||
| @ -30,146 +30,150 @@ export class AddonModWorkshopOfflineProvider { | ||||
|     static EVALUATE_SUBMISSIONS_TABLE = 'addon_mod_workshop_evaluate_submissions'; | ||||
|     static EVALUATE_ASSESSMENTS_TABLE = 'addon_mod_workshop_evaluate_assessments'; | ||||
| 
 | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonModWorkshopOfflineProvider.SUBMISSIONS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'workshopid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'submissionid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'action', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'title', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'content', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attachmentsid', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER', | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['workshopid', 'submissionid', 'action'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModWorkshopOfflineProvider.ASSESSMENTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'workshopid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'assessmentid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'inputdata', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['workshopid', 'assessmentid'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModWorkshopOfflineProvider.EVALUATE_SUBMISSIONS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'workshopid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'submissionid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'feedbacktext', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'published', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'gradeover', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['workshopid', 'submissionid'] | ||||
|         }, | ||||
|         { | ||||
|             name: AddonModWorkshopOfflineProvider.EVALUATE_ASSESSMENTS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'workshopid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'assessmentid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'feedbacktext', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'weight', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'gradinggradeover', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['workshopid', 'assessmentid'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonModWorkshopOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonModWorkshopOfflineProvider.SUBMISSIONS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'workshopid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'submissionid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'action', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'title', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'content', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attachmentsid', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER', | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['workshopid', 'submissionid', 'action'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModWorkshopOfflineProvider.ASSESSMENTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'workshopid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'assessmentid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'inputdata', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['workshopid', 'assessmentid'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModWorkshopOfflineProvider.EVALUATE_SUBMISSIONS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'workshopid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'submissionid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'feedbacktext', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'published', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'gradeover', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['workshopid', 'submissionid'] | ||||
|             }, | ||||
|             { | ||||
|                 name: AddonModWorkshopOfflineProvider.EVALUATE_ASSESSMENTS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'workshopid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'assessmentid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'feedbacktext', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'weight', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'gradinggradeover', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['workshopid', 'assessmentid'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private fileProvider: CoreFileProvider, | ||||
|             private sitesProvider: CoreSitesProvider, | ||||
|             private textUtils: CoreTextUtilsProvider, | ||||
|             private timeUtils: CoreTimeUtilsProvider) { | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| 
 | ||||
| /** | ||||
| @ -26,46 +26,50 @@ export class AddonNotesOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static NOTES_TABLE = 'addon_notes_offline_notes'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: AddonNotesOfflineProvider.NOTES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'publishstate', | ||||
|                     type: 'TEXT', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'content', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'format', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'created', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'lastmodified', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['userid', 'content', 'created'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'AddonNotesOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: AddonNotesOfflineProvider.NOTES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'publishstate', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'content', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'format', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'created', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'lastmodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['userid', 'content', 'created'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider,  private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider) { | ||||
|         this.logger = logger.getInstance('AddonNotesOfflineProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -28,6 +28,7 @@ import { CoreConfigProvider } from '@providers/config'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { CoreConfigConstants } from '../../../configconstants'; | ||||
| import { ILocalNotification } from '@ionic-native/local-notifications'; | ||||
| import { SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to handle push notifications. | ||||
| @ -41,7 +42,7 @@ export class AddonPushNotificationsProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static BADGE_TABLE = 'addon_pushnotifications_badge'; | ||||
|     protected tablesSchema = [ | ||||
|     protected tablesSchema: SQLiteDBTableSchema[] = [ | ||||
|         { | ||||
|             name: AddonPushNotificationsProvider.BADGE_TABLE, | ||||
|             columns: [ | ||||
|  | ||||
| @ -166,47 +166,8 @@ export class CoreSite { | ||||
|     protected wsProvider: CoreWSProvider; | ||||
| 
 | ||||
|     // Variables for the database.
 | ||||
|     protected WS_CACHE_TABLE = 'wscache'; | ||||
|     protected CONFIG_TABLE = 'core_site_config'; | ||||
|     protected tableSchemas = [ | ||||
|         { | ||||
|             name: this.WS_CACHE_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'id', | ||||
|                     type: 'TEXT', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'data', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'key', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'expirationTime', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             name: this.CONFIG_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                     unique: true, | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'value' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
| 
 | ||||
|     ]; | ||||
|     static WS_CACHE_TABLE = 'wscache'; | ||||
|     static CONFIG_TABLE = 'core_site_config'; | ||||
| 
 | ||||
|     // Versions of Moodle releases.
 | ||||
|     protected MOODLE_RELEASES = { | ||||
| @ -267,7 +228,6 @@ export class CoreSite { | ||||
|      */ | ||||
|     initDB(): void { | ||||
|         this.db = this.dbProvider.getDB('Site-' + this.id); | ||||
|         this.db.createTablesFromSchema(this.tableSchemas); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -784,10 +744,10 @@ export class CoreSite { | ||||
|         let promise; | ||||
| 
 | ||||
|         if (preSets.getCacheUsingCacheKey || (emergency && preSets.getEmergencyCacheUsingCacheKey)) { | ||||
|             promise = this.db.getRecords(this.WS_CACHE_TABLE, { key: preSets.cacheKey }).then((entries) => { | ||||
|             promise = this.db.getRecords(CoreSite.WS_CACHE_TABLE, { key: preSets.cacheKey }).then((entries) => { | ||||
|                 if (!entries.length) { | ||||
|                     // Cache key not found, get by params sent.
 | ||||
|                     return this.db.getRecord(this.WS_CACHE_TABLE, { id: id }); | ||||
|                     return this.db.getRecord(CoreSite.WS_CACHE_TABLE, { id: id }); | ||||
|                 } else if (entries.length > 1) { | ||||
|                     // More than one entry found. Search the one with same ID as this call.
 | ||||
|                     for (let i = 0, len = entries.length; i < len; i++) { | ||||
| @ -801,13 +761,13 @@ export class CoreSite { | ||||
|                 return entries[0]; | ||||
|             }); | ||||
|         } else { | ||||
|             promise = this.db.getRecord(this.WS_CACHE_TABLE, { id: id }).catch(() => { | ||||
|             promise = this.db.getRecord(CoreSite.WS_CACHE_TABLE, { id: id }).catch(() => { | ||||
|                 // Entry not found, try to get it using the old ID.
 | ||||
|                 const oldId = this.getCacheOldId(method, originalData || {}); | ||||
| 
 | ||||
|                 return this.db.getRecord(this.WS_CACHE_TABLE, { id: oldId }).then((entry) => { | ||||
|                 return this.db.getRecord(CoreSite.WS_CACHE_TABLE, { id: oldId }).then((entry) => { | ||||
|                     // Update the entry ID to use the new one.
 | ||||
|                     this.db.updateRecords(this.WS_CACHE_TABLE, {id: id}, {id: oldId}); | ||||
|                     this.db.updateRecords(CoreSite.WS_CACHE_TABLE, {id: id}, {id: oldId}); | ||||
| 
 | ||||
|                     return entry; | ||||
|                 }); | ||||
| @ -877,7 +837,7 @@ export class CoreSite { | ||||
|                 entry.key = preSets.cacheKey; | ||||
|             } | ||||
| 
 | ||||
|             return this.db.insertRecord(this.WS_CACHE_TABLE, entry); | ||||
|             return this.db.insertRecord(CoreSite.WS_CACHE_TABLE, entry); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| @ -898,10 +858,10 @@ export class CoreSite { | ||||
|         const id = this.getCacheId(method, data); | ||||
| 
 | ||||
|         if (allCacheKey) { | ||||
|             return this.db.deleteRecords(this.WS_CACHE_TABLE, { key: preSets.cacheKey }); | ||||
|             return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, { key: preSets.cacheKey }); | ||||
|         } | ||||
| 
 | ||||
|         return this.db.deleteRecords(this.WS_CACHE_TABLE, { id: id }); | ||||
|         return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, { id: id }); | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
| @ -935,7 +895,7 @@ export class CoreSite { | ||||
| 
 | ||||
|         this.logger.debug('Invalidate all the cache for site: ' + this.id); | ||||
| 
 | ||||
|         return this.db.updateRecords(this.WS_CACHE_TABLE, { expirationTime: 0 }); | ||||
|         return this.db.updateRecords(CoreSite.WS_CACHE_TABLE, { expirationTime: 0 }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -954,7 +914,7 @@ export class CoreSite { | ||||
| 
 | ||||
|         this.logger.debug('Invalidate cache for key: ' + key); | ||||
| 
 | ||||
|         return this.db.updateRecords(this.WS_CACHE_TABLE, { expirationTime: 0 }, { key: key }); | ||||
|         return this.db.updateRecords(CoreSite.WS_CACHE_TABLE, { expirationTime: 0 }, { key: key }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -997,7 +957,7 @@ export class CoreSite { | ||||
| 
 | ||||
|         this.logger.debug('Invalidate cache for key starting with: ' + key); | ||||
| 
 | ||||
|         const sql = 'UPDATE ' + this.WS_CACHE_TABLE + ' SET expirationTime=0 WHERE key LIKE ?'; | ||||
|         const sql = 'UPDATE ' + CoreSite.WS_CACHE_TABLE + ' SET expirationTime=0 WHERE key LIKE ?'; | ||||
| 
 | ||||
|         return this.db.execute(sql, [key + '%']); | ||||
|     } | ||||
| @ -1590,7 +1550,7 @@ export class CoreSite { | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     deleteSiteConfig(name: string): Promise<any> { | ||||
|         return this.db.deleteRecords(this.CONFIG_TABLE, { name: name }); | ||||
|         return this.db.deleteRecords(CoreSite.CONFIG_TABLE, { name: name }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -1601,7 +1561,7 @@ export class CoreSite { | ||||
|      * @return {Promise<any>} Resolves upon success along with the config data. Reject on failure. | ||||
|      */ | ||||
|     getLocalSiteConfig(name: string, defaultValue?: any): Promise<any> { | ||||
|         return this.db.getRecord(this.CONFIG_TABLE, { name: name }).then((entry) => { | ||||
|         return this.db.getRecord(CoreSite.CONFIG_TABLE, { name: name }).then((entry) => { | ||||
|             return entry.value; | ||||
|         }).catch((error) => { | ||||
|             if (typeof defaultValue != 'undefined') { | ||||
| @ -1620,6 +1580,6 @@ export class CoreSite { | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     setLocalSiteConfig(name: string, value: number | string): Promise<any> { | ||||
|         return this.db.insertRecord(this.CONFIG_TABLE, { name: name, value: value }); | ||||
|         return this.db.insertRecord(CoreSite.CONFIG_TABLE, { name: name, value: value }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -15,6 +15,129 @@ | ||||
| import { SQLite, SQLiteObject } from '@ionic-native/sqlite'; | ||||
| import { Platform } from 'ionic-angular'; | ||||
| 
 | ||||
| /** | ||||
|  * Schema of a table. | ||||
|  */ | ||||
| export interface SQLiteDBTableSchema { | ||||
|     /** | ||||
|      * The table name. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     name: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The columns to create in the table. | ||||
|      * @type {SQLiteDBColumnSchema[]} | ||||
|      */ | ||||
|     columns: SQLiteDBColumnSchema[]; | ||||
| 
 | ||||
|     /** | ||||
|      * Names of columns that are primary key. Use it for compound primary keys. | ||||
|      * @type {string[]} | ||||
|      */ | ||||
|     primaryKeys?: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * List of sets of unique columns. E.g: [['section', 'title'], ['author', 'title']]. | ||||
|      * @type {string[][]} | ||||
|      */ | ||||
|     uniqueKeys?: string[][]; | ||||
| 
 | ||||
|     /** | ||||
|      * List of foreign keys. | ||||
|      * @type {SQLiteDBForeignKeySchema[]} | ||||
|      */ | ||||
|     foreignKeys?: SQLiteDBForeignKeySchema[]; | ||||
| 
 | ||||
|     /** | ||||
|      * Check constraint for the table. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     tableCheck?: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Schema of a column. | ||||
|  */ | ||||
| export interface SQLiteDBColumnSchema { | ||||
|     /** | ||||
|      * Column's name. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     name: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Column's type. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     type?: 'INTEGER' | 'REAL' | 'TEXT' | 'BLOB'; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether the column is a primary key. Use it only if primary key is a single column. | ||||
|      * @type {boolean} | ||||
|      */ | ||||
|     primaryKey?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether it should be autoincremented. Only if primaryKey is true. | ||||
|      * @type {boolean} | ||||
|      */ | ||||
|     autoIncrement?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * True if column shouldn't be null. | ||||
|      * @type {boolean} | ||||
|      */ | ||||
|     notNull?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * WWhether the column is unique. | ||||
|      * @type {boolean} | ||||
|      */ | ||||
|     unique?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Check constraint for the column. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     check?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Default value for the column. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     default?: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Schema of a foreign key. | ||||
|  */ | ||||
| export interface SQLiteDBForeignKeySchema { | ||||
|     /** | ||||
|      * Columns to include in this foreign key. | ||||
|      * @type {string[]} | ||||
|      */ | ||||
|     columns: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * The external table referenced by this key. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     table: string; | ||||
| 
 | ||||
|     /** | ||||
|      * List of referenced columns from the referenced table. | ||||
|      * @type {string[]} | ||||
|      */ | ||||
|     foreignColumns?: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * Text with the actions to apply to the foreign key. | ||||
|      * @type {string} | ||||
|      */ | ||||
|     actions?: string; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Class to interact with the local database. | ||||
|  * | ||||
| @ -43,27 +166,15 @@ export class SQLiteDB { | ||||
|      * Helper function to create a table if it doesn't exist. | ||||
|      * | ||||
|      * @param {string} name The table name. | ||||
|      * @param {any[]} columns The columns to create in the table. Each column can have: | ||||
|      *                    * {string} name  Column's name. | ||||
|      *                    * {string} [type] Column's type. | ||||
|      *                    * {boolean} [primaryKey] If column is primary key. Use it only if primary key is a single column. | ||||
|      *                    * {boolean} [autoIncrement] Whether it should be autoincremented. Only if primaryKey is true. | ||||
|      *                    * {boolean} [notNull] True if column shouldn't be null. | ||||
|      *                    * {boolean} [unique] Whether the column is unique. | ||||
|      *                    * {string} [check] Check constraint for the column. | ||||
|      *                    * {string} [default] Default value for the column. | ||||
|      * @param {SQLiteDBColumnSchema[]} columns The columns to create in the table. | ||||
|      * @param {string[]} [primaryKeys] Names of columns that are primary key. Use it for compound primary keys. | ||||
|      * @param {string[][]} [uniqueKeys] List of sets of unique columns. E.g: [['section', 'title'], ['author', 'title']]. | ||||
|      * @param {any[]} [foreignKeys] List of foreign keys. Each key can have: | ||||
|      *                    * {string[]} columns Columns to include in this foreign key. | ||||
|      *                    * {string} table The external table referenced by this key. | ||||
|      *                    * {string[]} [foreignColumns] List of referenced columns from the referenced table. | ||||
|      *                    * {string} [actions] Text with the actions to apply to the foreign key. | ||||
|      * @param {SQLiteDBForeignKeySchema[]} [foreignKeys] List of foreign keys. | ||||
|      * @param {string} [tableCheck] Check constraint for the table. | ||||
|      * @return SQL query. | ||||
|      */ | ||||
|     buildCreateTableSql(name: string, columns: any[], primaryKeys?: string[], uniqueKeys?: string[][], foreignKeys?: any[], | ||||
|             tableCheck?: string): string { | ||||
|     buildCreateTableSql(name: string, columns: SQLiteDBColumnSchema[], primaryKeys?: string[], uniqueKeys?: string[][], | ||||
|             foreignKeys?: SQLiteDBForeignKeySchema[], tableCheck?: string): string { | ||||
|         const columnsSql = []; | ||||
|         let sql = `CREATE TABLE IF NOT EXISTS ${name} (`; | ||||
| 
 | ||||
| @ -207,27 +318,15 @@ export class SQLiteDB { | ||||
|      * Create a table if it doesn't exist. | ||||
|      * | ||||
|      * @param {string} name The table name. | ||||
|      * @param {any[]} columns The columns to create in the table. Each column can have: | ||||
|      *                    * {string} name  Column's name. | ||||
|      *                    * {string} [type] Column's type. | ||||
|      *                    * {boolean} [primaryKey] If column is primary key. Use it only if primary key is a single column. | ||||
|      *                    * {boolean} [autoIncrement] Whether it should be autoincremented. Only if primaryKey is true. | ||||
|      *                    * {boolean} [notNull] True if column shouldn't be null. | ||||
|      *                    * {boolean} [unique] Whether the column is unique. | ||||
|      *                    * {string} [check] Check constraint for the column. | ||||
|      *                    * {string} [default] Default value for the column. | ||||
|      * @param {SQLiteDBColumnSchema[]} columns The columns to create in the table. | ||||
|      * @param {string[]} [primaryKeys] Names of columns that are primary key. Use it for compound primary keys. | ||||
|      * @param {string[][]} [uniqueKeys] List of sets of unique columns. E.g: [['section', 'title'], ['author', 'title']]. | ||||
|      * @param {any[]} [foreignKeys] List of foreign keys. Each key can have: | ||||
|      *                    * {string[]} columns Columns to include in this foreign key. | ||||
|      *                    * {string} table The external table referenced by this key. | ||||
|      *                    * {string[]} [foreignColumns] List of referenced columns from the referenced table. | ||||
|      *                    * {string} [actions] Text with the actions to apply to the foreign key. | ||||
|      * @param {SQLiteDBForeignKeySchema[]} [foreignKeys] List of foreign keys. | ||||
|      * @param {string} [tableCheck] Check constraint for the table. | ||||
|      * @return {Promise<any>} Promise resolved when success. | ||||
|      */ | ||||
|     createTable(name: string, columns: any[], primaryKeys?: string[], uniqueKeys?: string[][], foreignKeys?: any[], | ||||
|             tableCheck?: string): Promise<any> { | ||||
|     createTable(name: string, columns: SQLiteDBColumnSchema[], primaryKeys?: string[], uniqueKeys?: string[][], | ||||
|             foreignKeys?: SQLiteDBForeignKeySchema[], tableCheck?: string): Promise<any> { | ||||
|         const sql = this.buildCreateTableSql(name, columns, primaryKeys, uniqueKeys, foreignKeys, tableCheck); | ||||
| 
 | ||||
|         return this.execute(sql); | ||||
| @ -236,10 +335,10 @@ export class SQLiteDB { | ||||
|     /** | ||||
|      * Create a table if it doesn't exist from a schema. | ||||
|      * | ||||
|      * @param {any} table Table schema. | ||||
|      * @param {SQLiteDBTableSchema} table Table schema. | ||||
|      * @return {Promise<any>} Promise resolved when success. | ||||
|      */ | ||||
|     createTableFromSchema(table: any): Promise<any> { | ||||
|     createTableFromSchema(table: SQLiteDBTableSchema): Promise<any> { | ||||
|         return this.createTable(table.name, table.columns, table.primaryKeys, table.uniqueKeys, | ||||
|             table.foreignKeys, table.tableCheck); | ||||
|     } | ||||
| @ -247,10 +346,10 @@ export class SQLiteDB { | ||||
|     /** | ||||
|      * Create several tables if they don't exist from a list of schemas. | ||||
|      * | ||||
|      * @param {any[]} tables List of table schema. | ||||
|      * @param {SQLiteDBTableSchema[]} tables List of table schema. | ||||
|      * @return {Promise<any>} Promise resolved when success. | ||||
|      */ | ||||
|     createTablesFromSchema(tables: any[]): Promise<any> { | ||||
|     createTablesFromSchema(tables: SQLiteDBTableSchema[]): Promise<any> { | ||||
|         const promises = []; | ||||
|         tables.forEach((table) => { | ||||
|             promises.push(this.createTableFromSchema(table)); | ||||
| @ -308,6 +407,16 @@ export class SQLiteDB { | ||||
|         return this.execute(`DELETE FROM ${table} ${select}`, params); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Drop a table if it exists. | ||||
|      * | ||||
|      * @param {string} name The table name. | ||||
|      * @return {Promise<any>} Promise resolved when success. | ||||
|      */ | ||||
|     dropTable(name: string): Promise<any> { | ||||
|         return this.execute(`DROP TABLE IF EXISTS ${name}`); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Execute a SQL query. | ||||
|      * IMPORTANT: Use this function only if you cannot use any of the other functions in this API. Please take into account that | ||||
| @ -684,6 +793,23 @@ export class SQLiteDB { | ||||
|         return this.executeBatch(statements); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Insert multiple records into database from another table. | ||||
|      * | ||||
|      * @param {string} table The database table to be inserted into. | ||||
|      * @param {string} source The database table to get the records from. | ||||
|      * @param {object} [conditions] The conditions to build the where clause. Must not contain numeric indexes. | ||||
|      * @param {string} [fields='*'] A comma separated list of fields to return. | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     insertRecordsFrom(table: string, source: string, conditions?: object, fields: string = '*'): Promise<any> { | ||||
|         const selectAndParams = this.whereClause(conditions); | ||||
|         const select = selectAndParams[0] ? 'WHERE ' + selectAndParams[0] : ''; | ||||
|         const params = selectAndParams[1]; | ||||
| 
 | ||||
|         return this.execute(`INSERT INTO ${table} SELECT ${fields} FROM ${source} ${select}`, params); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Ensures that limit params are numeric and positive integers, to be passed to the database. | ||||
|      * We explicitly treat null, '' and -1 as 0 in order to provide compatibility with how limit | ||||
| @ -776,6 +902,16 @@ export class SQLiteDB { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Test whether a table exists.. | ||||
|      * | ||||
|      * @param {string} name The table name. | ||||
|      * @return {Promise<void>} Promise resolved if exists, rejected otherwise. | ||||
|      */ | ||||
|     tableExists(name: string): Promise<void> { | ||||
|         return this.recordExists('sqlite_master', {type: 'table', tbl_name: name}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Update one or more records in a table. | ||||
|      * | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to handle offline data for courses. | ||||
| @ -23,37 +23,41 @@ export class CoreCourseOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static MANUAL_COMPLETION_TABLE = 'course_manual_completion'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: CoreCourseOfflineProvider.MANUAL_COMPLETION_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'cmid', | ||||
|                     type: 'INTEGER', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'completed', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'courseid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'coursename', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecompleted', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreCourseOfflineProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: CoreCourseOfflineProvider.MANUAL_COMPLETION_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'cmid', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'completed', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'courseid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'coursename', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecompleted', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private sitesProvider: CoreSitesProvider) { | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -17,7 +17,7 @@ import { TranslateService } from '@ngx-translate/core'; | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreEventsProvider } from '@providers/events'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| import { CoreSiteWSPreSets, CoreSite } from '@classes/site'; | ||||
| @ -47,34 +47,40 @@ export class CoreCourseProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     protected COURSE_STATUS_TABLE = 'course_status'; | ||||
|     protected courseStatusTableSchema = { | ||||
|         name: this.COURSE_STATUS_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreCourseProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'id', | ||||
|                 type: 'INTEGER', | ||||
|                 primaryKey: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'status', | ||||
|                 type: 'TEXT', | ||||
|                 notNull: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'previous', | ||||
|                 type: 'TEXT' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'updated', | ||||
|                 type: 'INTEGER' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'downloadTime', | ||||
|                 type: 'INTEGER' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'previousDownloadTime', | ||||
|                 type: 'INTEGER' | ||||
|                 name: this.COURSE_STATUS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'status', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'previous', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'updated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'downloadTime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'previousDownloadTime', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -91,7 +97,7 @@ export class CoreCourseProvider { | ||||
|             private courseOffline: CoreCourseOfflineProvider, private appProvider: CoreAppProvider) { | ||||
|         this.logger = logger.getInstance('CoreCourseProvider'); | ||||
| 
 | ||||
|         this.sitesProvider.createTableFromSchema(this.courseStatusTableSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -17,7 +17,7 @@ import { CoreEventsProvider } from '@providers/events'; | ||||
| import { CoreFileProvider } from '@providers/file'; | ||||
| import { CoreFilepoolProvider } from '@providers/filepool'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| import { CoreCourseProvider } from './course'; | ||||
| @ -202,18 +202,24 @@ export interface CoreCourseModulePrefetchHandler extends CoreDelegateHandler { | ||||
| export class CoreCourseModulePrefetchDelegate extends CoreDelegate { | ||||
|     // Variables for database.
 | ||||
|     protected CHECK_UPDATES_TIMES_TABLE = 'check_updates_times'; | ||||
|     protected checkUpdatesTableSchema = { | ||||
|         name: this.CHECK_UPDATES_TIMES_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreCourseModulePrefetchDelegate', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'courseId', | ||||
|                 type: 'INTEGER', | ||||
|                 primaryKey: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'time', | ||||
|                 type: 'INTEGER', | ||||
|                 notNull: true | ||||
|                 name: this.CHECK_UPDATES_TIMES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'courseId', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'time', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -242,7 +248,7 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { | ||||
|             protected eventsProvider: CoreEventsProvider) { | ||||
|         super('CoreCourseModulePrefetchDelegate', loggerProvider, sitesProvider, eventsProvider); | ||||
| 
 | ||||
|         this.sitesProvider.createTableFromSchema(this.checkUpdatesTableSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
| 
 | ||||
|         eventsProvider.on(CoreEventsProvider.LOGOUT, this.clearStatusCache.bind(this)); | ||||
|         eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => { | ||||
|  | ||||
| @ -20,7 +20,7 @@ import { LocalNotifications, ILocalNotification } from '@ionic-native/local-noti | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreInitDelegate, CoreInitHandler } from '@providers/init'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { FileTransferErrorMock } from './file-transfer'; | ||||
| @ -40,33 +40,37 @@ export class CoreEmulatorHelperProvider implements CoreInitHandler { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     protected LAST_RECEIVED_NOTIFICATION_TABLE = 'core_emulator_last_received_notification'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: this.LAST_RECEIVED_NOTIFICATION_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'component', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'id', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timecreated', | ||||
|                     type: 'INTEGER', | ||||
|                 }, | ||||
|             ], | ||||
|             primaryKeys: ['component'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreEmulatorHelperProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: this.LAST_RECEIVED_NOTIFICATION_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timecreated', | ||||
|                         type: 'INTEGER', | ||||
|                     }, | ||||
|                 ], | ||||
|                 primaryKeys: ['component'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(private file: File, private fileProvider: CoreFileProvider, private utils: CoreUtilsProvider, | ||||
|             logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private localNotif: LocalNotifications, | ||||
|             private captureHelper: CoreEmulatorCaptureHelperProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private appProvider: CoreAppProvider, private localNotifProvider: CoreLocalNotificationsProvider) { | ||||
|         this.logger = logger.getInstance('CoreEmulatorHelper'); | ||||
|         sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -17,7 +17,7 @@ import { LocalNotifications, ILocalNotification, ILocalNotificationAction } from | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { CoreConfigConstants } from '../../../configconstants'; | ||||
| import * as moment from 'moment'; | ||||
| @ -43,7 +43,7 @@ export class LocalNotificationsMock extends LocalNotifications { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     protected DESKTOP_NOTIFS_TABLE = 'desktop_local_notifications'; | ||||
|     protected tableSchema = { | ||||
|     protected tableSchema: SQLiteDBTableSchema = { | ||||
|         name: this.DESKTOP_NOTIFS_TABLE, | ||||
|         columns: [ | ||||
|             { | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| 
 | ||||
| @ -63,86 +63,90 @@ export class CoreQuestionProvider { | ||||
|     // Variables for database.
 | ||||
|     protected QUESTION_TABLE = 'questions'; | ||||
|     protected QUESTION_ANSWERS_TABLE = 'question_answers'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: this.QUESTION_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'component', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attemptid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'slot', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'componentid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'number', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'state', | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['component', 'attemptid', 'slot'] | ||||
|         }, | ||||
|         { | ||||
|             name: this.QUESTION_ANSWERS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'component', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'attemptid', | ||||
|                     type: 'INTEGER', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'componentid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'userid', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'questionslot', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'value', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['component', 'attemptid', 'name'] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreQuestionProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: this.QUESTION_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attemptid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'slot', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'componentid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'number', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'state', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['component', 'attemptid', 'slot'] | ||||
|             }, | ||||
|             { | ||||
|                 name: this.QUESTION_ANSWERS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'attemptid', | ||||
|                         type: 'INTEGER', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'componentid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'userid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'questionslot', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'value', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['component', 'attemptid', 'name'] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     protected QUESTION_PREFIX_REGEX = /q\d+:(\d+)_/; | ||||
|     protected STATES: {[name: string]: CoreQuestionState} = { | ||||
| @ -244,7 +248,7 @@ export class CoreQuestionProvider { | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider, | ||||
|             private utils: CoreUtilsProvider) { | ||||
|         this.logger = logger.getInstance('CoreQuestionProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -21,7 +21,7 @@ import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { Md5 } from 'ts-md5/dist/md5'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| 
 | ||||
| /** | ||||
|  * Service to share files with the app. | ||||
| @ -32,7 +32,7 @@ export class CoreSharedFilesProvider { | ||||
| 
 | ||||
|     // Variables for the database.
 | ||||
|     protected SHARED_FILES_TABLE = 'shared_files'; | ||||
|     protected tableSchema = { | ||||
|     protected tableSchema: SQLiteDBTableSchema = { | ||||
|         name: this.SHARED_FILES_TABLE, | ||||
|         columns: [ | ||||
|             { | ||||
|  | ||||
| @ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; | ||||
| import { CoreFilepoolProvider } from '@providers/filepool'; | ||||
| import { CoreLoggerProvider } from '@providers/logger'; | ||||
| import { CoreSite } from '@classes/site'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; | ||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||
| 
 | ||||
| /** | ||||
| @ -31,33 +31,37 @@ export class CoreUserProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     protected USERS_TABLE = 'users'; | ||||
|     protected tablesSchema = [ | ||||
|         { | ||||
|             name: this.USERS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'id', | ||||
|                     type: 'INTEGER', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'fullname', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'profileimageurl', | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ]; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreUserProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: this.USERS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'fullname', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'profileimageurl', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     protected logger; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, | ||||
|             private filepoolProvider: CoreFilepoolProvider) { | ||||
|         this.logger = logger.getInstance('CoreUserProvider'); | ||||
|         this.sitesProvider.createTablesFromSchema(this.tablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreAppProvider } from './app'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| 
 | ||||
| /** | ||||
|  * Factory to provide access to dynamic and permanent config and settings. | ||||
| @ -24,7 +24,7 @@ import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| export class CoreConfigProvider { | ||||
|     protected appDB: SQLiteDB; | ||||
|     protected TABLE_NAME = 'core_config'; | ||||
|     protected tableSchema = { | ||||
|     protected tableSchema: SQLiteDBTableSchema = { | ||||
|         name: this.TABLE_NAME, | ||||
|         columns: [ | ||||
|             { | ||||
|  | ||||
| @ -19,7 +19,7 @@ import { CoreConfigProvider } from './config'; | ||||
| import { CoreLoggerProvider } from './logger'; | ||||
| import { CoreUtilsProvider } from './utils/utils'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| 
 | ||||
| /** | ||||
|  * Interface that all cron handlers must implement. | ||||
| @ -94,7 +94,7 @@ export class CoreCronDelegate { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     protected CRON_TABLE = 'cron'; | ||||
|     protected tableSchema = { | ||||
|     protected tableSchema: SQLiteDBTableSchema = { | ||||
|         name: this.CRON_TABLE, | ||||
|         columns: [ | ||||
|             { | ||||
|  | ||||
| @ -20,7 +20,7 @@ import { CoreFileProvider } from './file'; | ||||
| import { CoreInitDelegate } from './init'; | ||||
| import { CoreLoggerProvider } from './logger'; | ||||
| import { CorePluginFileDelegate } from './plugin-file-delegate'; | ||||
| import { CoreSitesProvider } from './sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from './sites'; | ||||
| import { CoreWSProvider } from './ws'; | ||||
| import { CoreDomUtilsProvider } from './utils/dom'; | ||||
| import { CoreMimetypeUtilsProvider } from './utils/mimetype'; | ||||
| @ -28,7 +28,7 @@ import { CoreTextUtilsProvider } from './utils/text'; | ||||
| import { CoreTimeUtilsProvider } from './utils/time'; | ||||
| import { CoreUrlUtilsProvider } from './utils/url'; | ||||
| import { CoreUtilsProvider } from './utils/utils'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { Md5 } from 'ts-md5/dist/md5'; | ||||
| 
 | ||||
| @ -254,7 +254,7 @@ export class CoreFilepoolProvider { | ||||
|     protected FILES_TABLE = 'filepool_files'; // Downloaded files.
 | ||||
|     protected LINKS_TABLE = 'filepool_files_links'; // Links between downloaded files and components.
 | ||||
|     protected PACKAGES_TABLE = 'filepool_packages'; // Downloaded packages (sets of files).
 | ||||
|     protected appTablesSchema = [ | ||||
|     protected appTablesSchema: SQLiteDBTableSchema[] = [ | ||||
|         { | ||||
|             name: this.QUEUE_TABLE, | ||||
|             columns: [ | ||||
| @ -306,115 +306,119 @@ export class CoreFilepoolProvider { | ||||
|             primaryKeys: ['siteId', 'fileId'] | ||||
|         } | ||||
|     ]; | ||||
|     protected sitesTablesSchema = [ | ||||
|         { | ||||
|             name: this.FILES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'fileId', | ||||
|                     type: 'TEXT', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'url', | ||||
|                     type: 'TEXT', | ||||
|                     notNull: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'revision', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'timemodified', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'stale', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'downloadTime', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'isexternalfile', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'repositorytype', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'path', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'extension', | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             name: this.LINKS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'fileId', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'component', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'componentId', | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ], | ||||
|             primaryKeys: ['fileId', 'component', 'componentId'] | ||||
|         }, | ||||
|         { | ||||
|             name: this.PACKAGES_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'id', | ||||
|                     type: 'TEXT', | ||||
|                     primaryKey: true | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'component', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'componentId', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'status', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'previous', | ||||
|                     type: 'TEXT' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'updated', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'downloadTime', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'previousDownloadTime', | ||||
|                     type: 'INTEGER' | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'extra', | ||||
|                     type: 'TEXT' | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|     ]; | ||||
|     protected siteSchma: CoreSiteSchema = { | ||||
|         name: 'CoreFilepoolProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: this.FILES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'fileId', | ||||
|                         type: 'TEXT', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'url', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'revision', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'timemodified', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'stale', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'downloadTime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'isexternalfile', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'repositorytype', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'path', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'extension', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 name: this.LINKS_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'fileId', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'componentId', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['fileId', 'component', 'componentId'] | ||||
|             }, | ||||
|             { | ||||
|                 name: this.PACKAGES_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'TEXT', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'componentId', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'status', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'previous', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'updated', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'downloadTime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'previousDownloadTime', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'extra', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     protected logger; | ||||
|     protected appDB: SQLiteDB; | ||||
| @ -443,7 +447,7 @@ export class CoreFilepoolProvider { | ||||
|         this.appDB = this.appProvider.getDB(); | ||||
|         this.appDB.createTablesFromSchema(this.appTablesSchema); | ||||
| 
 | ||||
|         this.sitesProvider.createTablesFromSchema(this.sitesTablesSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchma); | ||||
| 
 | ||||
|         initDelegate.ready().then(() => { | ||||
|             // Waiting for the app to be ready to start processing the queue.
 | ||||
|  | ||||
| @ -22,7 +22,7 @@ import { CoreEventsProvider } from './events'; | ||||
| import { CoreLoggerProvider } from './logger'; | ||||
| import { CoreTextUtilsProvider } from './utils/text'; | ||||
| import { CoreUtilsProvider } from './utils/utils'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { Subject, Subscription } from 'rxjs'; | ||||
| 
 | ||||
| @ -38,7 +38,7 @@ export class CoreLocalNotificationsProvider { | ||||
|     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 TRIGGERED_TABLE = 'notifications_triggered'; // Store to prevent re-triggering notifications.
 | ||||
|     protected tablesSchema = [ | ||||
|     protected tablesSchema: SQLiteDBTableSchema[] = [ | ||||
|         { | ||||
|             name: this.SITES_TABLE, | ||||
|             columns: [ | ||||
|  | ||||
| @ -25,7 +25,7 @@ import { CoreUtilsProvider } from './utils/utils'; | ||||
| import { CoreConstants } from '@core/constants'; | ||||
| import { CoreConfigConstants } from '../configconstants'; | ||||
| import { CoreSite } from '@classes/site'; | ||||
| import { SQLiteDB } from '@classes/sqlitedb'; | ||||
| import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; | ||||
| import { Md5 } from 'ts-md5/dist/md5'; | ||||
| 
 | ||||
| /** | ||||
| @ -127,6 +127,41 @@ export interface CoreSiteBasicInfo { | ||||
|     badge?: number; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Site schema and migration function. | ||||
|  */ | ||||
| export interface CoreSiteSchema { | ||||
|     /** | ||||
|      * Name of the schema. | ||||
|      * | ||||
|      * @type {string} | ||||
|      */ | ||||
|     name: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Latest version of the schema (integer greater than 0). | ||||
|      * | ||||
|      * @type {number} | ||||
|      */ | ||||
|     version: number; | ||||
| 
 | ||||
|     /** | ||||
|      * Tables to create when installing or upgrading the schema. | ||||
|      */ | ||||
|     tables?: SQLiteDBTableSchema[]; | ||||
| 
 | ||||
|     /** | ||||
|      * Migrates the schema in a site to the latest version. | ||||
|      * | ||||
|      * Called when installing and upgrading the schema, after creating the defined tables. | ||||
|      * | ||||
|      * @param {SQLiteDB} db Site database. | ||||
|      * @param {number} oldVersion Old version of the schema or 0 if not installed. | ||||
|      * @return {Promise<any> | void} Promise resolved when done. | ||||
|      */ | ||||
|     migrate?(db: SQLiteDB, oldVersion: number): Promise<any> | void; | ||||
| } | ||||
| 
 | ||||
| /* | ||||
|  * Service to manage and interact with sites. | ||||
|  * It allows creating tables in the databases of all sites. Each service or component should be responsible of creating | ||||
| @ -143,7 +178,8 @@ export class CoreSitesProvider { | ||||
|     // Variables for the database.
 | ||||
|     protected SITES_TABLE = 'sites'; | ||||
|     protected CURRENT_SITE_TABLE = 'current_site'; | ||||
|     protected appTablesSchema = [ | ||||
|     protected SCHEMA_VERSIONS_TABLE = 'schema_versions'; | ||||
|     protected appTablesSchema: SQLiteDBTableSchema[] = [ | ||||
|         { | ||||
|             name: this.SITES_TABLE, | ||||
|             columns: [ | ||||
| @ -208,7 +244,70 @@ export class CoreSitesProvider { | ||||
|     protected currentSite: CoreSite; | ||||
|     protected sites: { [s: string]: CoreSite } = {}; | ||||
|     protected appDB: SQLiteDB; | ||||
|     protected siteTablesSchemas = []; // Schemas for site tables. Other providers can add schemas in here.
 | ||||
|     protected siteSchemasMigration: { [siteId: string]: Promise<any> } = {}; | ||||
| 
 | ||||
|     // Schemas for site tables. Other providers can add schemas in here.
 | ||||
|     protected siteSchemas: { [name: string]: CoreSiteSchema } = {}; | ||||
|     protected siteTablesSchemas: SQLiteDBTableSchema[] = [ | ||||
|         { | ||||
|             name: this.SCHEMA_VERSIONS_TABLE, | ||||
|             columns: [ | ||||
|                 { | ||||
|                     name: 'name', | ||||
|                     type: 'TEXT', | ||||
|                     primaryKey: true, | ||||
|                 }, | ||||
|                 { | ||||
|                     name: 'version', | ||||
|                     type: 'INTEGER' | ||||
|                 } | ||||
|             ] | ||||
|         } | ||||
|     ]; | ||||
| 
 | ||||
|     // Site schema for this provider.
 | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreSitesProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: CoreSite.WS_CACHE_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'TEXT', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'data', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'key', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'expirationTime', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 name: CoreSite.CONFIG_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'name', | ||||
|                         type: 'TEXT', | ||||
|                         unique: true, | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'value' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     constructor(logger: CoreLoggerProvider, private http: HttpClient, private sitesFactory: CoreSitesFactoryProvider, | ||||
|             private appProvider: CoreAppProvider, private translate: TranslateService, private urlUtils: CoreUrlUtilsProvider, | ||||
| @ -218,6 +317,7 @@ export class CoreSitesProvider { | ||||
| 
 | ||||
|         this.appDB = appProvider.getDB(); | ||||
|         this.appDB.createTablesFromSchema(this.appTablesSchema); | ||||
|         this.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -478,24 +578,23 @@ export class CoreSitesProvider { | ||||
|                 candidateSite.setId(siteId); | ||||
|                 candidateSite.setInfo(info); | ||||
| 
 | ||||
|                 // Try to get the site config.
 | ||||
|                 return this.getSiteConfig(candidateSite).then((config) => { | ||||
|                     candidateSite.setConfig(config); | ||||
|                     // Add site to sites list.
 | ||||
|                     this.addSite(siteId, siteUrl, token, info, privateToken, config); | ||||
|                     // Turn candidate site into current site.
 | ||||
|                     this.currentSite = candidateSite; | ||||
|                     this.sites[siteId] = candidateSite; | ||||
|                     // Store session.
 | ||||
|                     this.login(siteId); | ||||
|                     this.eventsProvider.trigger(CoreEventsProvider.SITE_ADDED, info, siteId); | ||||
|                 // Create database tables before login and before any WS call.
 | ||||
|                 return this.migrateSiteSchemas(candidateSite).then(() => { | ||||
| 
 | ||||
|                     if (this.siteTablesSchemas.length) { | ||||
|                         // Create tables in the site's database.
 | ||||
|                         candidateSite.getDb().createTablesFromSchema(this.siteTablesSchemas); | ||||
|                     } | ||||
|                     // Try to get the site config.
 | ||||
|                     return this.getSiteConfig(candidateSite).then((config) => { | ||||
|                         candidateSite.setConfig(config); | ||||
|                         // Add site to sites list.
 | ||||
|                         this.addSite(siteId, siteUrl, token, info, privateToken, config); | ||||
|                         // Turn candidate site into current site.
 | ||||
|                         this.currentSite = candidateSite; | ||||
|                         this.sites[siteId] = candidateSite; | ||||
|                         // Store session.
 | ||||
|                         this.login(siteId); | ||||
|                         this.eventsProvider.trigger(CoreEventsProvider.SITE_ADDED, info, siteId); | ||||
| 
 | ||||
|                     return siteId; | ||||
|                         return siteId; | ||||
|                     }); | ||||
|                 }); | ||||
|             } else if (result == this.LEGACY_APP_VERSION) { | ||||
|                 let errorKey = 'core.login.legacymoodleversion', | ||||
| @ -830,10 +929,10 @@ export class CoreSitesProvider { | ||||
|      * Create a site from an entry of the sites list DB. The new site is added to the list of "cached" sites: this.sites. | ||||
|      * | ||||
|      * @param {any} entry Site list entry. | ||||
|      * @return {CoreSite} Created site. | ||||
|      * @return {Promise<CoreSite>} Promised resolved with the created site. | ||||
|      */ | ||||
|     makeSiteFromSiteListEntry(entry: any): CoreSite { | ||||
|         let site, | ||||
|     makeSiteFromSiteListEntry(entry: any): Promise<CoreSite> { | ||||
|         let site: CoreSite, | ||||
|             info = entry.info, | ||||
|             config = entry.config; | ||||
| 
 | ||||
| @ -843,13 +942,13 @@ export class CoreSitesProvider { | ||||
| 
 | ||||
|         site = this.sitesFactory.makeSite(entry.id, entry.siteUrl, entry.token, | ||||
|             info, entry.privateToken, config, entry.loggedOut == 1); | ||||
|         this.sites[entry.id] = site; | ||||
|         if (this.siteTablesSchemas.length) { | ||||
|             // Create tables in the site's database.
 | ||||
|             site.getDb().createTablesFromSchema(this.siteTablesSchemas); | ||||
|         } | ||||
| 
 | ||||
|         return site; | ||||
|         return this.migrateSiteSchemas(site).then(() => { | ||||
|             // Set site after migrating schemas, or a call to getSite could get the site while tables are being created.
 | ||||
|             this.sites[entry.id] = site; | ||||
| 
 | ||||
|             return site; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -1178,9 +1277,11 @@ export class CoreSitesProvider { | ||||
| 
 | ||||
|         return this.appDB.getAllRecords(this.SITES_TABLE).then((siteEntries) => { | ||||
|             const ids = []; | ||||
|             const promises = []; | ||||
| 
 | ||||
|             siteEntries.forEach((site) => { | ||||
|                 if (!this.sites[site.id]) { | ||||
|                     this.makeSiteFromSiteListEntry(site); | ||||
|                     promises.push(this.makeSiteFromSiteListEntry(site)); | ||||
|                 } | ||||
| 
 | ||||
|                 if (this.sites[site.id].containsUrl(url)) { | ||||
| @ -1190,7 +1291,9 @@ export class CoreSitesProvider { | ||||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|             return ids; | ||||
|             return Promise.all(promises).then(() => { | ||||
|                 return ids; | ||||
|             }); | ||||
|         }).catch(() => { | ||||
|             // Shouldn't happen.
 | ||||
|             return []; | ||||
| @ -1251,18 +1354,18 @@ export class CoreSitesProvider { | ||||
|     /** | ||||
|      * Create a table in all the sites databases. | ||||
|      * | ||||
|      * @param {any} table Table schema. | ||||
|      * @param {SQLiteDBTamableSchema} table Table schema. | ||||
|      */ | ||||
|     createTableFromSchema(table: any): void { | ||||
|     createTableFromSchema(table: SQLiteDBTableSchema): void { | ||||
|         this.createTablesFromSchema([table]); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create several tables in all the sites databases. | ||||
|      * | ||||
|      * @param {any[]} tables List of tables schema. | ||||
|      * @param {SQLiteDBTamableSchema[]} tables List of tables schema. | ||||
|      */ | ||||
|     createTablesFromSchema(tables: any[]): void { | ||||
|     createTablesFromSchema(tables: SQLiteDBTableSchema[]): void { | ||||
|         // Add the tables to the list of schemas. This list is to create all the tables in new sites.
 | ||||
|         this.siteTablesSchemas = this.siteTablesSchemas.concat(tables); | ||||
| 
 | ||||
| @ -1294,4 +1397,70 @@ export class CoreSitesProvider { | ||||
|     isLegacyMoodleByInfo(info: any): boolean { | ||||
|         return this.isValidMoodleVersion(info) == this.LEGACY_APP_VERSION; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Register a site schema. | ||||
|      */ | ||||
|     registerSiteSchema(schema: CoreSiteSchema): void { | ||||
|         this.siteSchemas[schema.name] = schema; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Install and upgrade all the registered schemas and tables. | ||||
|      * | ||||
|      * @param {CoreSite} site Site. | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     migrateSiteSchemas(site: CoreSite): Promise<any> { | ||||
|         const db = site.getDb(); | ||||
| 
 | ||||
|         if (this.siteSchemasMigration[site.id]) { | ||||
|             return this.siteSchemasMigration[site.id]; | ||||
|         } | ||||
| 
 | ||||
|         this.logger.debug(`Migrating all schemas of ${site.id}`); | ||||
| 
 | ||||
|         // First create tables not registerd with name/version.
 | ||||
|         const promise = db.createTablesFromSchema(this.siteTablesSchemas).then(() => { | ||||
|             // Fetch installed versions of the schema.
 | ||||
|             return db.getAllRecords(this.SCHEMA_VERSIONS_TABLE).then((records) => { | ||||
|                 const versions = {}; | ||||
|                 records.forEach((record) => { | ||||
|                     versions[record.name] = record.version; | ||||
|                 }); | ||||
| 
 | ||||
|                 const promises = []; | ||||
|                 for (const name in this.siteSchemas) { | ||||
|                     const schema = this.siteSchemas[name]; | ||||
|                     const oldVersion = versions[name] || 0; | ||||
|                     if (oldVersion >= schema.version) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     this.logger.debug(`Migrating schema '${name}' of ${site.id} from version ${oldVersion} to ${schema.version}`); | ||||
| 
 | ||||
|                     let promise: Promise<any> = Promise.resolve(); | ||||
|                     if (schema.tables) { | ||||
|                         promise = promise.then(() => db.createTablesFromSchema(schema.tables)); | ||||
|                     } | ||||
|                     if (schema.migrate) { | ||||
|                         promise = promise.then(() => schema.migrate(db, oldVersion)); | ||||
|                     } | ||||
| 
 | ||||
|                     // Set installed version.
 | ||||
|                     promise = promise.then(() => db.insertRecord(this.SCHEMA_VERSIONS_TABLE, {name, version: schema.version})); | ||||
| 
 | ||||
|                     promises.push(promise); | ||||
|                 } | ||||
| 
 | ||||
|                 return Promise.all(promises); | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|         this.siteSchemasMigration[site.id] = promise; | ||||
| 
 | ||||
|         return promise.finally(() => { | ||||
|             delete this.siteSchemasMigration[site.id]; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreEventsProvider } from './events'; | ||||
| import { CoreSitesProvider } from './sites'; | ||||
| import { CoreSitesProvider, CoreSiteSchema } from './sites'; | ||||
| 
 | ||||
| /* | ||||
|  * Service that provides some features regarding synchronization. | ||||
| @ -24,36 +24,42 @@ export class CoreSyncProvider { | ||||
| 
 | ||||
|     // Variables for the database.
 | ||||
|     protected SYNC_TABLE = 'sync'; | ||||
|     protected tableSchema = { | ||||
|         name: this.SYNC_TABLE, | ||||
|         columns: [ | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreSyncProvider', | ||||
|         version: 1, | ||||
|         tables: [ | ||||
|             { | ||||
|                 name: 'component', | ||||
|                 type: 'TEXT', | ||||
|                 notNull: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'id', | ||||
|                 type: 'TEXT', | ||||
|                 notNull: true | ||||
|             }, | ||||
|             { | ||||
|                 name: 'time', | ||||
|                 type: 'INTEGER' | ||||
|             }, | ||||
|             { | ||||
|                 name: 'warnings', | ||||
|                 type: 'TEXT' | ||||
|                 name: this.SYNC_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'id', | ||||
|                         type: 'TEXT', | ||||
|                         notNull: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'time', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'warnings', | ||||
|                         type: 'TEXT' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['component', 'id'] | ||||
|             } | ||||
|         ], | ||||
|         primaryKeys: ['component', 'id'] | ||||
|         ] | ||||
|     }; | ||||
| 
 | ||||
|     // Store blocked sync objects.
 | ||||
|     protected blockedItems: { [siteId: string]: { [blockId: string]: { [operation: string]: boolean } } } = {}; | ||||
| 
 | ||||
|     constructor(eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider) { | ||||
|         this.sitesProvider.createTableFromSchema(this.tableSchema); | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
| 
 | ||||
|         // Unblock all blocks on logout.
 | ||||
|         eventsProvider.on(CoreEventsProvider.LOGOUT, (data) => { | ||||
|  | ||||
| @ -4,6 +4,7 @@ information provided here is intended especially for developers. | ||||
| === 3.6.1 === | ||||
| 
 | ||||
| - The local notifications plugin was updated to its latest version. The new API has some breaking changes, so please check its documentation if you're using local notifications. Also, you need to run "npm install" to update the ionic-native library. | ||||
| - New method CoreSitesProvider.registerSiteSchema allows to register table schemas and migration functions for site databases. Prefer this method over CoreSitesProvider.createTablesFromSchema: it supports schema migrations and it tracks the installed version of the schema, so it does not try to create the tables on every app boot. | ||||
| 
 | ||||
| === 3.6.0 === | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user