forked from EVOgeek/Vmeda.Online
		
	MOBILE-4304 scorm: Update database usage
This commit is contained in:
		
							parent
							
								
									38d0ad1aad
								
							
						
					
					
						commit
						b6f32dfddd
					
				| @ -13,7 +13,6 @@ | |||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Injectable } from '@angular/core'; | import { Injectable } from '@angular/core'; | ||||||
| import { SQLiteDB } from '@classes/sqlitedb'; |  | ||||||
| import { CoreUser } from '@features/user/services/user'; | import { CoreUser } from '@features/user/services/user'; | ||||||
| import { CoreSites } from '@services/sites'; | import { CoreSites } from '@services/sites'; | ||||||
| import { CoreSync } from '@services/sync'; | import { CoreSync } from '@services/sync'; | ||||||
| @ -38,6 +37,10 @@ import { | |||||||
|     AddonModScormUserDataMap, |     AddonModScormUserDataMap, | ||||||
|     AddonModScormWSSco, |     AddonModScormWSSco, | ||||||
| } from './scorm'; | } from './scorm'; | ||||||
|  | import { lazyMap, LazyMap } from '@/core/utils/lazy-map'; | ||||||
|  | import { asyncInstance, AsyncInstance } from '@/core/utils/async-instance'; | ||||||
|  | import { CoreDatabaseTable } from '@classes/database/database-table'; | ||||||
|  | import { CoreDatabaseCachingStrategy } from '@classes/database/database-table-proxy'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Service to handle offline SCORM. |  * Service to handle offline SCORM. | ||||||
| @ -47,8 +50,36 @@ export class AddonModScormOfflineProvider { | |||||||
| 
 | 
 | ||||||
|     protected logger: CoreLogger; |     protected logger: CoreLogger; | ||||||
| 
 | 
 | ||||||
|  |     protected tracksTables: LazyMap< | ||||||
|  |         AsyncInstance<CoreDatabaseTable<AddonModScormTrackDBRecord, 'scormid' | 'userid' | 'attempt' | 'scoid' | 'element'>> | ||||||
|  |     >; | ||||||
|  | 
 | ||||||
|  |     protected attemptsTables: LazyMap< | ||||||
|  |         AsyncInstance<CoreDatabaseTable<AddonModScormAttemptDBRecord, 'scormid' | 'userid' | 'attempt'>> | ||||||
|  |     >; | ||||||
|  | 
 | ||||||
|     constructor() { |     constructor() { | ||||||
|         this.logger = CoreLogger.getInstance('AddonModScormOfflineProvider'); |         this.logger = CoreLogger.getInstance('AddonModScormOfflineProvider'); | ||||||
|  |         this.tracksTables = lazyMap( | ||||||
|  |             siteId => asyncInstance( | ||||||
|  |                 () => CoreSites.getSiteTable(TRACKS_TABLE_NAME, { | ||||||
|  |                     siteId, | ||||||
|  |                     primaryKeyColumns: ['scormid', 'userid', 'attempt', 'scoid', 'element'], | ||||||
|  |                     config: { cachingStrategy: CoreDatabaseCachingStrategy.None }, | ||||||
|  |                     onDestroy: () => delete this.tracksTables[siteId], | ||||||
|  |                 }), | ||||||
|  |             ), | ||||||
|  |         ); | ||||||
|  |         this.attemptsTables = lazyMap( | ||||||
|  |             siteId => asyncInstance( | ||||||
|  |                 () => CoreSites.getSiteTable(ATTEMPTS_TABLE_NAME, { | ||||||
|  |                     siteId, | ||||||
|  |                     primaryKeyColumns: ['scormid', 'userid', 'attempt'], | ||||||
|  |                     config: { cachingStrategy: CoreDatabaseCachingStrategy.None }, | ||||||
|  |                     onDestroy: () => delete this.tracksTables[siteId], | ||||||
|  |                 }), | ||||||
|  |             ), | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -76,40 +107,43 @@ export class AddonModScormOfflineProvider { | |||||||
| 
 | 
 | ||||||
|         this.logger.debug(`Change attempt number from ${attempt} to ${newAttempt} in SCORM ${scormId}`); |         this.logger.debug(`Change attempt number from ${attempt} to ${newAttempt} in SCORM ${scormId}`); | ||||||
| 
 | 
 | ||||||
|         // Update the attempt number.
 |  | ||||||
|         const db = site.getDb(); |  | ||||||
|         const currentAttemptConditions: AddonModScormOfflineDBCommonData = { |  | ||||||
|             scormid: scormId, |  | ||||||
|             userid: userId, |  | ||||||
|             attempt, |  | ||||||
|         }; |  | ||||||
|         const newAttemptConditions: AddonModScormOfflineDBCommonData = { |  | ||||||
|             scormid: scormId, |  | ||||||
|             userid: userId, |  | ||||||
|             attempt: newAttempt, |  | ||||||
|         }; |  | ||||||
|         const newAttemptData: Partial<AddonModScormAttemptDBRecord> = { |  | ||||||
|             attempt: newAttempt, |  | ||||||
|             timemodified: CoreTimeUtils.timestamp(), |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         // Block the SCORM so it can't be synced.
 |         // Block the SCORM so it can't be synced.
 | ||||||
|         CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scormId, 'changeAttemptNumber', site.id); |         CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scormId, 'changeAttemptNumber', site.id); | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             await db.updateRecords(ATTEMPTS_TABLE_NAME, newAttemptData, currentAttemptConditions); |             const currentAttemptConditions = { | ||||||
|  |                 sql: 'scormid = ? AND userid = ? AND attempt = ?', | ||||||
|  |                 sqlParams: [scormId, userId, attempt], | ||||||
|  |                 js: (record: AddonModScormOfflineDBCommonData) => | ||||||
|  |                     record.scormid === scormId && | ||||||
|  |                     record.userid === userId && | ||||||
|  |                     record.attempt === attempt, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             await this.attemptsTables[site.id].updateWhere( | ||||||
|  |                 { attempt: newAttempt, timemodified: CoreTimeUtils.timestamp() }, | ||||||
|  |                 currentAttemptConditions, | ||||||
|  |             ); | ||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
|                 // Now update the attempt number of all the tracks and mark them as not synced.
 |                 // Now update the attempt number of all the tracks and mark them as not synced.
 | ||||||
|                 const newTrackData: Partial<AddonModScormTrackDBRecord> = { |                 await this.tracksTables[site.id].updateWhere( | ||||||
|                     attempt: newAttempt, |                     { attempt: newAttempt, synced: 0 }, | ||||||
|                     synced: 0, |                     currentAttemptConditions, | ||||||
|                 }; |                 ); | ||||||
| 
 |  | ||||||
|                 await db.updateRecords(TRACKS_TABLE_NAME, newTrackData, currentAttemptConditions); |  | ||||||
|             } catch (error) { |             } catch (error) { | ||||||
|                 // Failed to update the tracks, restore the old attempt number.
 |                 // Failed to update the tracks, restore the old attempt number.
 | ||||||
|                 await db.updateRecords(ATTEMPTS_TABLE_NAME, { attempt }, newAttemptConditions); |                 await this.attemptsTables[site.id].updateWhere( | ||||||
|  |                     { attempt }, | ||||||
|  |                     { | ||||||
|  |                         sql: 'scormid = ? AND userid = ? AND attempt = ?', | ||||||
|  |                         sqlParams: [scormId, userId, newAttempt], | ||||||
|  |                         js: (attempt) => | ||||||
|  |                             attempt.scormid === scormId && | ||||||
|  |                             attempt.userid === userId && | ||||||
|  |                             attempt.attempt === newAttempt, | ||||||
|  |                     }, | ||||||
|  |                 ); | ||||||
| 
 | 
 | ||||||
|                 throw error; |                 throw error; | ||||||
|             } |             } | ||||||
| @ -148,7 +182,6 @@ export class AddonModScormOfflineProvider { | |||||||
|         CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'createNewAttempt', site.id); |         CoreSync.blockOperation(AddonModScormProvider.COMPONENT, scorm.id, 'createNewAttempt', site.id); | ||||||
| 
 | 
 | ||||||
|         // Create attempt in DB.
 |         // Create attempt in DB.
 | ||||||
|         const db = site.getDb(); |  | ||||||
|         const entry: AddonModScormAttemptDBRecord = { |         const entry: AddonModScormAttemptDBRecord = { | ||||||
|             scormid: scorm.id, |             scormid: scorm.id, | ||||||
|             userid: userId, |             userid: userId, | ||||||
| @ -166,7 +199,7 @@ export class AddonModScormOfflineProvider { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             await db.insertRecord(ATTEMPTS_TABLE_NAME, entry); |             await this.attemptsTables[site.id].insert(entry); | ||||||
| 
 | 
 | ||||||
|             // Store all the data in userData.
 |             // Store all the data in userData.
 | ||||||
|             const promises: Promise<void>[] = []; |             const promises: Promise<void>[] = []; | ||||||
| @ -204,16 +237,15 @@ export class AddonModScormOfflineProvider { | |||||||
| 
 | 
 | ||||||
|         this.logger.debug(`Delete offline attempt ${attempt} in SCORM ${scormId}`); |         this.logger.debug(`Delete offline attempt ${attempt} in SCORM ${scormId}`); | ||||||
| 
 | 
 | ||||||
|         const db = site.getDb(); |         const conditions = { | ||||||
|         const conditions: AddonModScormOfflineDBCommonData = { |  | ||||||
|             scormid: scormId, |             scormid: scormId, | ||||||
|             userid: userId, |             userid: userId, | ||||||
|             attempt, |             attempt, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         await Promise.all([ |         await Promise.all([ | ||||||
|             db.deleteRecords(ATTEMPTS_TABLE_NAME, conditions), |             this.attemptsTables[site.id].delete(conditions), | ||||||
|             db.deleteRecords(TRACKS_TABLE_NAME, conditions), |             this.tracksTables[site.id].delete(conditions), | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -280,9 +312,9 @@ export class AddonModScormOfflineProvider { | |||||||
|      * @returns Promise resolved when the offline attempts are retrieved. |      * @returns Promise resolved when the offline attempts are retrieved. | ||||||
|      */ |      */ | ||||||
|     async getAllAttempts(siteId?: string): Promise<AddonModScormOfflineAttempt[]> { |     async getAllAttempts(siteId?: string): Promise<AddonModScormOfflineAttempt[]> { | ||||||
|         const db = await CoreSites.getSiteDb(siteId); |         siteId ??= CoreSites.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         const attempts = await db.getAllRecords<AddonModScormAttemptDBRecord>(ATTEMPTS_TABLE_NAME); |         const attempts = await this.attemptsTables[siteId].getMany(); | ||||||
| 
 | 
 | ||||||
|         return attempts.map((attempt) => this.parseAttempt(attempt)); |         return attempts.map((attempt) => this.parseAttempt(attempt)); | ||||||
|     } |     } | ||||||
| @ -300,7 +332,7 @@ export class AddonModScormOfflineProvider { | |||||||
|         const site = await CoreSites.getSite(siteId); |         const site = await CoreSites.getSite(siteId); | ||||||
|         userId = userId || site.getUserId(); |         userId = userId || site.getUserId(); | ||||||
| 
 | 
 | ||||||
|         const attemptRecord = await site.getDb().getRecord<AddonModScormAttemptDBRecord>(ATTEMPTS_TABLE_NAME, { |         const attemptRecord = await this.attemptsTables[site.id].getOneByPrimaryKey({ | ||||||
|             scormid: scormId, |             scormid: scormId, | ||||||
|             userid: userId, |             userid: userId, | ||||||
|             attempt, |             attempt, | ||||||
| @ -340,7 +372,7 @@ export class AddonModScormOfflineProvider { | |||||||
|         const site = await CoreSites.getSite(siteId); |         const site = await CoreSites.getSite(siteId); | ||||||
|         userId = userId || site.getUserId(); |         userId = userId || site.getUserId(); | ||||||
| 
 | 
 | ||||||
|         const attempts = await site.getDb().getRecords<AddonModScormAttemptDBRecord>(ATTEMPTS_TABLE_NAME, { |         const attempts = await this.attemptsTables[site.id].getMany({ | ||||||
|             scormid: scormId, |             scormid: scormId, | ||||||
|             userid: userId, |             userid: userId, | ||||||
|         }); |         }); | ||||||
| @ -428,7 +460,7 @@ export class AddonModScormOfflineProvider { | |||||||
|             conditions.synced = 1; |             conditions.synced = 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const tracks = await site.getDb().getRecords<AddonModScormTrackDBRecord>(TRACKS_TABLE_NAME, conditions); |         const tracks = await this.tracksTables[site.id].getMany(conditions); | ||||||
| 
 | 
 | ||||||
|         return this.parseTracks(tracks); |         return this.parseTracks(tracks); | ||||||
|     } |     } | ||||||
| @ -598,7 +630,6 @@ export class AddonModScormOfflineProvider { | |||||||
|         userId = userId || site.getUserId(); |         userId = userId || site.getUserId(); | ||||||
| 
 | 
 | ||||||
|         const scoUserData = scoData?.userdata || {}; |         const scoUserData = scoData?.userdata || {}; | ||||||
|         const db = site.getDb(); |  | ||||||
|         let lessonStatusInserted = false; |         let lessonStatusInserted = false; | ||||||
| 
 | 
 | ||||||
|         if (forceCompleted) { |         if (forceCompleted) { | ||||||
| @ -611,7 +642,16 @@ export class AddonModScormOfflineProvider { | |||||||
|                 if (scoUserData['cmi.core.lesson_status'] == 'incomplete') { |                 if (scoUserData['cmi.core.lesson_status'] == 'incomplete') { | ||||||
|                     lessonStatusInserted = true; |                     lessonStatusInserted = true; | ||||||
| 
 | 
 | ||||||
|                     await this.insertTrackToDB(db, userId, scormId, scoId, attempt, 'cmi.core.lesson_status', 'completed'); |                     await this.tracksTables[site.id].insert({ | ||||||
|  |                         userid: userId, | ||||||
|  |                         scormid: scormId, | ||||||
|  |                         scoid: scoId, | ||||||
|  |                         attempt, | ||||||
|  |                         element: 'cmi.core.lesson_status', | ||||||
|  |                         value: JSON.stringify('completed'), | ||||||
|  |                         timemodified: CoreTimeUtils.timestamp(), | ||||||
|  |                         synced: 0, | ||||||
|  |                     }); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -622,81 +662,35 @@ export class AddonModScormOfflineProvider { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             await this.insertTrackToDB(db, userId, scormId, scoId, attempt, element, value); |             await this.tracksTables[site.id].insert({ | ||||||
|  |                 userid: userId, | ||||||
|  |                 scormid: scormId, | ||||||
|  |                 scoid: scoId, | ||||||
|  |                 attempt, | ||||||
|  |                 element, | ||||||
|  |                 value: value === undefined ? null : JSON.stringify(value), | ||||||
|  |                 timemodified: CoreTimeUtils.timestamp(), | ||||||
|  |                 synced: 0, | ||||||
|  |             }); | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|             if (lessonStatusInserted) { |             if (lessonStatusInserted) { | ||||||
|                 // Rollback previous insert.
 |                 // Rollback previous insert.
 | ||||||
|                 await this.insertTrackToDB(db, userId, scormId, scoId, attempt, 'cmi.core.lesson_status', 'incomplete'); |                 await this.tracksTables[site.id].insert({ | ||||||
|  |                     userid: userId, | ||||||
|  |                     scormid: scormId, | ||||||
|  |                     scoid: scoId, | ||||||
|  |                     attempt, | ||||||
|  |                     element: 'cmi.core.lesson_status', | ||||||
|  |                     value: JSON.stringify('incomplete'), | ||||||
|  |                     timemodified: CoreTimeUtils.timestamp(), | ||||||
|  |                     synced: 0, | ||||||
|  |                 }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             throw error; |             throw error; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Insert a track in the DB. |  | ||||||
|      * |  | ||||||
|      * @param db Site's DB. |  | ||||||
|      * @param userId User ID. |  | ||||||
|      * @param scormId SCORM ID. |  | ||||||
|      * @param scoId SCO ID. |  | ||||||
|      * @param attempt Attempt number. |  | ||||||
|      * @param element Name of the element to insert. |  | ||||||
|      * @param value Value of the element to insert. |  | ||||||
|      * @param synchronous True if insert should NOT return a promise. Please use it only if synchronous is a must. |  | ||||||
|      * @returns Returns a promise if synchronous=false, otherwise returns a boolean. |  | ||||||
|      */ |  | ||||||
|     protected insertTrackToDB( |  | ||||||
|         db: SQLiteDB, |  | ||||||
|         userId: number, |  | ||||||
|         scormId: number, |  | ||||||
|         scoId: number, |  | ||||||
|         attempt: number, |  | ||||||
|         element: string, |  | ||||||
|         value: AddonModScormDataValue | undefined, |  | ||||||
|         synchronous: true, |  | ||||||
|     ): boolean; |  | ||||||
|     protected insertTrackToDB( |  | ||||||
|         db: SQLiteDB, |  | ||||||
|         userId: number, |  | ||||||
|         scormId: number, |  | ||||||
|         scoId: number, |  | ||||||
|         attempt: number, |  | ||||||
|         element: string, |  | ||||||
|         value?: AddonModScormDataValue, |  | ||||||
|         synchronous?: false, |  | ||||||
|     ): Promise<number>; |  | ||||||
|     protected insertTrackToDB( |  | ||||||
|         db: SQLiteDB, |  | ||||||
|         userId: number, |  | ||||||
|         scormId: number, |  | ||||||
|         scoId: number, |  | ||||||
|         attempt: number, |  | ||||||
|         element: string, |  | ||||||
|         value?: AddonModScormDataValue, |  | ||||||
|         synchronous?: boolean, |  | ||||||
|     ): boolean | Promise<number> { |  | ||||||
|         const entry: AddonModScormTrackDBRecord = { |  | ||||||
|             userid: userId, |  | ||||||
|             scormid: scormId, |  | ||||||
|             scoid: scoId, |  | ||||||
|             attempt, |  | ||||||
|             element: element, |  | ||||||
|             value: value === undefined ? null : JSON.stringify(value), |  | ||||||
|             timemodified: CoreTimeUtils.timestamp(), |  | ||||||
|             synced: 0, |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         if (synchronous) { |  | ||||||
|             // The insert operation is always asynchronous, always return true.
 |  | ||||||
|             db.insertRecord(TRACKS_TABLE_NAME, entry); |  | ||||||
| 
 |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return db.insertRecord(TRACKS_TABLE_NAME, entry); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Insert a track in the offline tracks store, returning a synchronous value. |      * Insert a track in the offline tracks store, returning a synchronous value. | ||||||
|      * Please use this function only if synchronous is a must. It's recommended to use insertTrack. |      * Please use this function only if synchronous is a must. It's recommended to use insertTrack. | ||||||
| @ -730,8 +724,7 @@ export class AddonModScormOfflineProvider { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const scoUserData = scoData?.userdata || {}; |         const scoUserData = scoData?.userdata || {}; | ||||||
|         const db = CoreSites.getRequiredCurrentSite().getDb(); |         const siteId = CoreSites.getRequiredCurrentSite().id; | ||||||
|         let lessonStatusInserted = false; |  | ||||||
| 
 | 
 | ||||||
|         if (forceCompleted) { |         if (forceCompleted) { | ||||||
|             if (element == 'cmi.core.lesson_status' && value == 'incomplete') { |             if (element == 'cmi.core.lesson_status' && value == 'incomplete') { | ||||||
| @ -741,11 +734,16 @@ export class AddonModScormOfflineProvider { | |||||||
|             } |             } | ||||||
|             if (element == 'cmi.core.score.raw') { |             if (element == 'cmi.core.score.raw') { | ||||||
|                 if (scoUserData['cmi.core.lesson_status'] == 'incomplete') { |                 if (scoUserData['cmi.core.lesson_status'] == 'incomplete') { | ||||||
|                     lessonStatusInserted = true; |                     this.tracksTables[siteId].syncInsert({ | ||||||
| 
 |                         userid: userId, | ||||||
|                     if (!this.insertTrackToDB(db, userId, scormId, scoId, attempt, 'cmi.core.lesson_status', 'completed', true)) { |                         scormid: scormId, | ||||||
|                         return false; |                         scoid: scoId, | ||||||
|                     } |                         attempt, | ||||||
|  |                         element: 'cmi.core.lesson_status', | ||||||
|  |                         value: JSON.stringify('completed'), | ||||||
|  |                         timemodified: CoreTimeUtils.timestamp(), | ||||||
|  |                         synced: 0, | ||||||
|  |                     }); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -755,15 +753,16 @@ export class AddonModScormOfflineProvider { | |||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!this.insertTrackToDB(db, userId, scormId, scoId, attempt, element, value, true)) { |         this.tracksTables[siteId].syncInsert({ | ||||||
|             // Insert failed.
 |             userid: userId, | ||||||
|             if (lessonStatusInserted) { |             scormid: scormId, | ||||||
|                 // Rollback previous insert.
 |             scoid: scoId, | ||||||
|                 this.insertTrackToDB(db, userId, scormId, scoId, attempt, 'cmi.core.lesson_status', 'incomplete', true); |             attempt, | ||||||
|             } |             element: element, | ||||||
| 
 |             value: value === undefined ? null : JSON.stringify(value), | ||||||
|             return false; |             timemodified: CoreTimeUtils.timestamp(), | ||||||
|         } |             synced: 0, | ||||||
|  |         }); | ||||||
| 
 | 
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| @ -784,7 +783,7 @@ export class AddonModScormOfflineProvider { | |||||||
| 
 | 
 | ||||||
|         this.logger.debug(`Mark SCO ${scoId} as synced for attempt ${attempt} in SCORM ${scormId}`); |         this.logger.debug(`Mark SCO ${scoId} as synced for attempt ${attempt} in SCORM ${scormId}`); | ||||||
| 
 | 
 | ||||||
|         await site.getDb().updateRecords(TRACKS_TABLE_NAME, { synced: 1 }, <Partial<AddonModScormTrackDBRecord>> { |         await this.tracksTables[site.id].update({ synced: 1 }, { | ||||||
|             scormid: scormId, |             scormid: scormId, | ||||||
|             userid: userId, |             userid: userId, | ||||||
|             attempt, |             attempt, | ||||||
| @ -971,10 +970,13 @@ export class AddonModScormOfflineProvider { | |||||||
|             snapshot: JSON.stringify(this.removeDefaultData(userData)), |             snapshot: JSON.stringify(this.removeDefaultData(userData)), | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         await site.getDb().updateRecords(ATTEMPTS_TABLE_NAME, newData, <Partial<AddonModScormAttemptDBRecord>> { |         await this.attemptsTables[site.id].updateWhere(newData, { | ||||||
|             scormid: scormId, |             sql: 'scormid = ? AND userid = ? AND attempt = ?', | ||||||
|             userid: userId, |             sqlParams: [scormId, userId, attempt], | ||||||
|             attempt, |             js: (record: AddonModScormOfflineDBCommonData) => | ||||||
|  |                 record.scormid === scormId && | ||||||
|  |                 record.userid === userId && | ||||||
|  |                 record.attempt === attempt, | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -258,6 +258,18 @@ export class CoreDatabaseTable< | |||||||
|         await this.database.insertRecord(this.tableName, record); |         await this.database.insertRecord(this.tableName, record); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Insert a new record synchronously. | ||||||
|  |      * | ||||||
|  |      * @param record Database record. | ||||||
|  |      */ | ||||||
|  |     syncInsert(record: DBRecord): void { | ||||||
|  |         // The current database architecture does not support synchronous operations,
 | ||||||
|  |         // so calling this method will mean that errors will be silenced. Because of that,
 | ||||||
|  |         // this should only be called if using the asynchronous alternatives is not possible.
 | ||||||
|  |         this.insert(record); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Update records matching the given conditions. |      * Update records matching the given conditions. | ||||||
|      * |      * | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user