From d0c93f6416b7ee7cecf0d520e64c377141fecded Mon Sep 17 00:00:00 2001 From: sam marshall Date: Fri, 11 Oct 2019 16:03:28 +0100 Subject: [PATCH 1/6] MOBILE-3188 Web services: Record component that owns WS cache item This commit adds optional component and componentId fields to the preSets variable, which are recorded in the wscache table. These are then used by (a) core site plugins where a module cmid is available, and (b) the forum (as an example core implementation) so that module site plugins and forum provide the new data. (Note that this is not going to be very useful where we retrieve data for multiple activities at once, which happens for activities like Page. Still, it is optional.) --- src/addon/mod/forum/components/index/index.ts | 3 +- .../mod/forum/pages/discussion/discussion.ts | 9 +++--- src/addon/mod/forum/providers/forum.ts | 24 +++++++++----- src/addon/mod/forum/providers/helper.ts | 5 +-- .../mod/forum/providers/prefetch-handler.ts | 5 +-- src/classes/site.ts | 20 +++++++++++- .../core-siteplugins-module-index.html | 2 +- .../components/module-index/module-index.ts | 2 ++ .../plugin-content/plugin-content.ts | 9 +++++- src/core/siteplugins/providers/siteplugins.ts | 9 +++++- src/providers/sites.ts | 32 +++++++++++++++++-- 11 files changed, 97 insertions(+), 23 deletions(-) diff --git a/src/addon/mod/forum/components/index/index.ts b/src/addon/mod/forum/components/index/index.ts index 6795fccac..34ea7ba6c 100644 --- a/src/addon/mod/forum/components/index/index.ts +++ b/src/addon/mod/forum/components/index/index.ts @@ -354,7 +354,8 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom this.page = 0; } - return this.forumProvider.getDiscussions(this.forum.id, this.selectedSortOrder.value, this.page).then((response) => { + return this.forumProvider.getDiscussions(this.forum.id, this.forum.cmid, + this.selectedSortOrder.value, this.page).then((response) => { let promise; if (this.usesGroups) { promise = this.forumProvider.formatDiscussionsGroups(this.forum.cmid, response.discussions); diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index 7ef3aa4de..2bfd3f449 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -323,7 +323,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { let ratingInfo; return syncPromise.then(() => { - return this.forumProvider.getDiscussionPosts(this.discussionId).then((response) => { + return this.forumProvider.getDiscussionPosts(this.discussionId, this.cmId).then((response) => { onlinePosts = response.posts; ratingInfo = response.ratinginfo; }).then(() => { @@ -412,7 +412,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { // The discussion object was not passed as parameter and there is no starting post. Should not happen. if (!this.discussion) { - promises.push(this.loadDiscussion(this.forumId, this.discussionId)); + promises.push(this.loadDiscussion(this.forumId, this.cmId, this.discussionId)); } return Promise.all(promises); @@ -479,13 +479,14 @@ export class AddonModForumDiscussionPage implements OnDestroy { * Convenience function to load discussion. * * @param forumId Forum ID. + * @param cmId Forum cmid. * @param discussionId Discussion ID. * @return Promise resolved when done. */ - protected loadDiscussion(forumId: number, discussionId: number): Promise { + protected loadDiscussion(forumId: number, cmId: number, discussionId: number): Promise { // Fetch the discussion if not passed as parameter. if (!this.discussion && forumId) { - return this.forumHelper.getDiscussionById(forumId, discussionId).then((discussion) => { + return this.forumHelper.getDiscussionById(forumId, cmId, discussionId).then((discussion) => { this.discussion = discussion; this.discussionId = this.discussion.discussion; }).catch(() => { diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts index 2c9d03cdb..fa6cebdfc 100644 --- a/src/addon/mod/forum/providers/forum.ts +++ b/src/addon/mod/forum/providers/forum.ts @@ -492,15 +492,18 @@ export class AddonModForumProvider { * Get forum discussion posts. * * @param discussionId Discussion ID. + * @param cmId Forum cmid. * @param siteId Site ID. If not defined, current site. * @return Promise resolved with forum posts and rating info. */ - getDiscussionPosts(discussionId: number, siteId?: string): Promise<{posts: any[], ratinginfo?: CoreRatingInfo}> { + getDiscussionPosts(discussionId: number, cmId: number, siteId?: string): Promise<{posts: any[], ratinginfo?: CoreRatingInfo}> { const params = { discussionid: discussionId }; const preSets = { - cacheKey: this.getDiscussionPostsCacheKey(discussionId) + cacheKey: this.getDiscussionPostsCacheKey(discussionId), + component: AddonModForumProvider.COMPONENT, + componentId: cmId }; return this.sitesProvider.getSite(siteId).then((site) => { @@ -592,6 +595,7 @@ export class AddonModForumProvider { * Get forum discussions. * * @param forumId Forum ID. + * @param cmId Forum cmid * @param sortOrder Sort order. * @param page Page. * @param forceCache True to always get the value from cache. false otherwise. @@ -601,7 +605,8 @@ export class AddonModForumProvider { * discussion ID is discussion.discussion. * - canLoadMore: True if there may be more discussions to load. */ - getDiscussions(forumId: number, sortOrder?: number, page: number = 0, forceCache?: boolean, siteId?: string): Promise { + getDiscussions(forumId: number, cmId: number, sortOrder?: number, page: number = 0, + forceCache?: boolean, siteId?: string): Promise { sortOrder = sortOrder || AddonModForumProvider.SORTORDER_LASTPOST_DESC; return this.sitesProvider.getSite(siteId).then((site) => { @@ -626,7 +631,9 @@ export class AddonModForumProvider { } } const preSets: CoreSiteWSPreSets = { - cacheKey: this.getDiscussionsListCacheKey(forumId, sortOrder) + cacheKey: this.getDiscussionsListCacheKey(forumId, sortOrder), + component: AddonModForumProvider.COMPONENT, + componentId: cmId }; if (forceCache) { preSets.omitExpires = true; @@ -673,6 +680,7 @@ export class AddonModForumProvider { * If a page fails, the discussions until that page will be returned along with a flag indicating an error occurred. * * @param forumId Forum ID. + * @param cmId Forum cmid. * @param sortOrder Sort order. * @param forceCache True to always get the value from cache, false otherwise. * @param numPages Number of pages to get. If not defined, all pages. @@ -682,8 +690,8 @@ export class AddonModForumProvider { * - discussions: List of discussions. * - error: True if an error occurred, false otherwise. */ - getDiscussionsInPages(forumId: number, sortOrder?: number, forceCache?: boolean, numPages?: number, startPage?: number, - siteId?: string): Promise { + getDiscussionsInPages(forumId: number, cmId: number, sortOrder?: number, forceCache?: boolean, + numPages?: number, startPage?: number, siteId?: string): Promise { if (typeof numPages == 'undefined') { numPages = -1; } @@ -700,7 +708,7 @@ export class AddonModForumProvider { const getPage = (page: number): Promise => { // Get page discussions. - return this.getDiscussions(forumId, sortOrder, page, forceCache, siteId).then((response) => { + return this.getDiscussions(forumId, cmId, sortOrder, page, forceCache, siteId).then((response) => { result.discussions = result.discussions.concat(response.discussions); numPages--; @@ -753,7 +761,7 @@ export class AddonModForumProvider { this.getAvailableSortOrders().forEach((sortOrder) => { // We need to get the list of discussions to be able to invalidate their posts. - promises.push(this.getDiscussionsInPages(forum.id, sortOrder.value, true).then((response) => { + promises.push(this.getDiscussionsInPages(forum.id, forum.cmid, sortOrder.value, true).then((response) => { // Now invalidate the WS calls. const promises = []; diff --git a/src/addon/mod/forum/providers/helper.ts b/src/addon/mod/forum/providers/helper.ts index 99ca1b487..7b3db2efa 100644 --- a/src/addon/mod/forum/providers/helper.ts +++ b/src/addon/mod/forum/providers/helper.ts @@ -270,15 +270,16 @@ export class AddonModForumHelperProvider { * This function is inefficient because it needs to fetch all discussion pages in the worst case. * * @param forumId Forum ID. + * @param cmId Forum cmid * @param discussionId Discussion ID. * @param siteId Site ID. If not defined, current site. * @return Promise resolved with the discussion data. */ - getDiscussionById(forumId: number, discussionId: number, siteId?: string): Promise { + getDiscussionById(forumId: number, cmId: number, discussionId: number, siteId?: string): Promise { siteId = siteId || this.sitesProvider.getCurrentSiteId(); const findDiscussion = (page: number): Promise => { - return this.forumProvider.getDiscussions(forumId, undefined, page, false, siteId).then((response) => { + return this.forumProvider.getDiscussions(forumId, cmId, undefined, page, false, siteId).then((response) => { if (response.discussions && response.discussions.length > 0) { // Note that discussion.id is the main post ID but discussion ID is discussion.discussion. const discussion = response.discussions.find((discussion) => discussion.discussion == discussionId); diff --git a/src/addon/mod/forum/providers/prefetch-handler.ts b/src/addon/mod/forum/providers/prefetch-handler.ts index 00af16f83..5a75af10a 100644 --- a/src/addon/mod/forum/providers/prefetch-handler.ts +++ b/src/addon/mod/forum/providers/prefetch-handler.ts @@ -114,7 +114,8 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand protected getPostsForPrefetch(forum: any, siteId?: string): Promise { const promises = this.forumProvider.getAvailableSortOrders().map((sortOrder) => { // Get discussions in first 2 pages. - return this.forumProvider.getDiscussionsInPages(forum.id, sortOrder.value, false, 2, 0, siteId).then((response) => { + return this.forumProvider.getDiscussionsInPages(forum.id, forum.cmid, + sortOrder.value, false, 2, 0, siteId).then((response) => { if (response.error) { return Promise.reject(null); } @@ -122,7 +123,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand const promises = []; response.discussions.forEach((discussion) => { - promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion, siteId)); + promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion, forum.cmid, siteId)); }); return Promise.all(promises); diff --git a/src/classes/site.ts b/src/classes/site.ts index 463b5a027..c24685ef3 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -127,6 +127,17 @@ export interface CoreSiteWSPreSets { * Defaults to CoreSite.FREQUENCY_USUALLY. */ updateFrequency?: number; + + /** + * Component name. Optionally included if this request is being made on behalf of a specific + * component (e.g. activity). + */ + component?: string; + + /** + * Component id. Optionally included when 'component' is set. + */ + componentId?: number; } /** @@ -197,7 +208,7 @@ export class CoreSite { protected wsProvider: CoreWSProvider; // Variables for the database. - static WS_CACHE_TABLE = 'wscache'; + static WS_CACHE_TABLE = 'ws_cache'; static CONFIG_TABLE = 'core_site_config'; // Versions of Moodle releases. @@ -1128,6 +1139,13 @@ export class CoreSite { entry.key = preSets.cacheKey; } + if (preSets.component) { + entry.component = preSets.component; + if (preSets.componentId) { + entry.componentId = preSets.componentId; + } + } + return this.db.insertRecord(CoreSite.WS_CACHE_TABLE, entry); }); } diff --git a/src/core/siteplugins/components/module-index/core-siteplugins-module-index.html b/src/core/siteplugins/components/module-index/core-siteplugins-module-index.html index 538055ea5..1662b918c 100644 --- a/src/core/siteplugins/components/module-index/core-siteplugins-module-index.html +++ b/src/core/siteplugins/components/module-index/core-siteplugins-module-index.html @@ -9,4 +9,4 @@ - + diff --git a/src/core/siteplugins/components/module-index/module-index.ts b/src/core/siteplugins/components/module-index/module-index.ts index 48a6621e8..60347d9d4 100644 --- a/src/core/siteplugins/components/module-index/module-index.ts +++ b/src/core/siteplugins/components/module-index/module-index.ts @@ -37,6 +37,7 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C @ViewChild(CoreSitePluginsPluginContentComponent) content: CoreSitePluginsPluginContentComponent; component: string; + componentId: number; method: string; args: any; initResult: any; @@ -77,6 +78,7 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C if (handler) { this.component = handler.plugin.component; + this.componentId = this.module.id; this.method = handler.handlerSchema.method; this.args = { courseid: this.courseId, diff --git a/src/core/siteplugins/components/plugin-content/plugin-content.ts b/src/core/siteplugins/components/plugin-content/plugin-content.ts index 632a64222..cc3b74ff0 100644 --- a/src/core/siteplugins/components/plugin-content/plugin-content.ts +++ b/src/core/siteplugins/components/plugin-content/plugin-content.ts @@ -32,6 +32,7 @@ export class CoreSitePluginsPluginContentComponent implements OnInit, DoCheck { @ViewChild('compile') compileComponent: ElementRef; @Input() component: string; + @Input() componentId?: number; @Input() method: string; @Input() args: any; @Input() initResult: any; // Result of the init WS call of the handler. @@ -92,7 +93,13 @@ export class CoreSitePluginsPluginContentComponent implements OnInit, DoCheck { this.forceCompile = false; - return this.sitePluginsProvider.getContent(this.component, this.method, this.args, this.preSets).then((result) => { + const preSets = Object.assign({}, this.preSets); + preSets.component = this.component; + if (this.componentId) { + preSets.componentId = this.componentId; + } + + return this.sitePluginsProvider.getContent(this.component, this.method, this.args, preSets).then((result) => { this.content = result.templates.length ? result.templates[0].html : ''; // Load first template. this.javascript = result.javascript; this.otherData = result.otherdata; diff --git a/src/core/siteplugins/providers/siteplugins.ts b/src/core/siteplugins/providers/siteplugins.ts index b70686dd5..18a38b374 100644 --- a/src/core/siteplugins/providers/siteplugins.ts +++ b/src/core/siteplugins/providers/siteplugins.ts @@ -514,7 +514,14 @@ export class CoreSitePluginsProvider { promises.push(this.callWS(method, params, {cacheKey: cacheKey})); } else { // It's a method to get content. - promises.push(this.getContent(component, method, args).then((result) => { + const preSets = { + component: component, + componentId: undefined + }; + if (module) { + preSets.componentId = module.id; + } + promises.push(this.getContent(component, method, args, preSets).then((result) => { const subPromises = []; // Prefetch the files in the content. diff --git a/src/providers/sites.ts b/src/providers/sites.ts index b25283c92..22062270c 100644 --- a/src/providers/sites.ts +++ b/src/providers/sites.ts @@ -360,7 +360,7 @@ export class CoreSitesProvider { // Site schema for this provider. protected siteSchema: CoreSiteSchema = { name: 'CoreSitesProvider', - version: 1, + version: 2, canBeCleared: [ CoreSite.WS_CACHE_TABLE ], tables: [ { @@ -382,6 +382,14 @@ export class CoreSitesProvider { { name: 'expirationTime', type: 'INTEGER' + }, + { + name: 'component', + type: 'TEXT' + }, + { + name: 'componentId', + type: 'INTEGER' } ] }, @@ -399,7 +407,27 @@ export class CoreSitesProvider { } ] } - ] + ], + async migrate (db: SQLiteDB, oldVersion: number, siteId: string): Promise { + if (oldVersion && oldVersion < 2) { + const newTable = CoreSite.WS_CACHE_TABLE; + const oldTable = 'wscache'; + + try { + await db.tableExists(oldTable); + } catch (error) { + // Old table does not exist, ignore. + return; + } + // Cannot use insertRecordsFrom because there are extra fields, so manually code INSERT INTO. + await db.execute( + 'INSERT INTO ' + newTable + ' ' + + 'SELECT id, data, key, expirationTime, NULL as component, NULL as componentId ' + + 'FROM ' + oldTable); + + return await db.dropTable(oldTable); + } + } }; constructor(logger: CoreLoggerProvider, From eced391288ecb661251df7d40473a091b4474926 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Wed, 16 Oct 2019 15:51:05 +0100 Subject: [PATCH 2/6] MOBILE-3188 Download interface: Show and delete total downloaded data When showing downloaded sizes in the context menu and in the 'Manage storage' screen, show the total size including downloaded files plus cached web service data. When deleting the downloaded data in either location, delete both kinds of data. --- .../pages/course-storage/course-storage.ts | 12 +++++- src/classes/site.ts | 42 +++++++++++++++++++ src/core/course/providers/helper.ts | 7 +++- .../providers/module-prefetch-delegate.ts | 30 +++++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/addon/storagemanager/pages/course-storage/course-storage.ts b/src/addon/storagemanager/pages/course-storage/course-storage.ts index 6bdeecc52..9e38df36c 100644 --- a/src/addon/storagemanager/pages/course-storage/course-storage.ts +++ b/src/addon/storagemanager/pages/course-storage/course-storage.ts @@ -20,6 +20,7 @@ import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { TranslateService } from '@ngx-translate/core'; import { CoreConstants } from '@core/constants'; +import { CoreSitesProvider } from '@providers/sites'; /** * Page that displays the amount of file storage used by each activity on the course, and allows @@ -39,6 +40,7 @@ export class AddonStorageManagerCourseStoragePage { totalSize: number; constructor(navParams: NavParams, + private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate, private courseHelperProvider: CoreCourseHelperProvider, @@ -70,7 +72,7 @@ export class AddonStorageManagerCourseStoragePage { // But these aren't necessarily consistent, for example mod_frog vs mmaModFrog. // There is nothing enforcing correct values. // Most modules which have large files are downloadable, so I think this is sufficient. - const promise = this.prefetchDelegate.getModuleDownloadedSize(module, this.course.id). + const promise = this.prefetchDelegate.getModuleTotalSize(module, this.course.id). then((size) => { // There are some cases where the return from this is not a valid number. if (!isNaN(size)) { @@ -185,7 +187,13 @@ export class AddonStorageManagerCourseStoragePage { modules.forEach((module) => { // Remove the files. const promise = this.prefetchDelegate.removeModuleFiles(module, this.course.id).then(() => { - // When the files are removed, update the size. + const handler = this.prefetchDelegate.getPrefetchHandlerFor(module); + if (handler) { + + return this.sitesProvider.getCurrentSite().deleteComponentFromCache(handler.component, module.id); + } + }).then(() => { + // When the files and cache are removed, update the size. module.parentSection.totalSize -= module.totalSize; this.totalSize -= module.totalSize; module.totalSize = 0; diff --git a/src/classes/site.ts b/src/classes/site.ts index c24685ef3..77f7e994f 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -1100,6 +1100,25 @@ export class CoreSite { }); } + /** + * Gets the size of cached data for a specific component or component instance. + * + * @param component Component name + * @param componentId Optional component id (if not included, returns sum for whole component) + * @return Promise resolved when we have calculated the size + */ + getComponentCacheSize(component: string, componentId?: string): Promise { + const params = [component]; + let extraClause = ''; + if (componentId) { + params.push(componentId); + extraClause = ' AND componentId = ?'; + } + + return this.db.getFieldSql('SELECT SUM(length(data)) FROM ' + CoreSite.WS_CACHE_TABLE + + ' WHERE component = ?' + extraClause, params); + } + /** * Save a WS response to cache. * @@ -1173,6 +1192,29 @@ export class CoreSite { return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, { id: id }); } + /** + * Deletes WS cache entries for all methods relating to a specific component (and + * optionally component id). + * + * @param component Component name. + * @param componentId Component id. + * @return Promise resolved when the entries are deleted. + */ + deleteComponentFromCache(component: string, componentId?: string): Promise { + if (!this.db) { + return Promise.reject(null); + } + + const params = { + component: component + } as any; + if (componentId) { + params.componentId = componentId; + } + + return this.db.deleteRecords(CoreSite.WS_CACHE_TABLE, params); + } + /* * Uploads a file using Cordova File API. * diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index 1ba933eac..870bced3c 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -425,6 +425,11 @@ export class CoreCourseHelperProvider { await this.prefetchDelegate.removeModuleFiles(module, courseId); + const handler = this.prefetchDelegate.getPrefetchHandlerFor(module); + if (handler) { + await this.sitesProvider.getCurrentSite().deleteComponentFromCache(handler.component, String(module.id)); + } + done && done(); } catch (error) { @@ -1131,7 +1136,7 @@ export class CoreCourseHelperProvider { this.prefetchDelegate.invalidateModuleStatusCache(module); } - promises.push(this.prefetchDelegate.getModuleDownloadedSize(module, courseId).then((moduleSize) => { + promises.push(this.prefetchDelegate.getModuleTotalSize(module, courseId).then((moduleSize) => { moduleInfo.size = moduleSize; moduleInfo.sizeReadable = this.textUtils.bytesToSize(moduleSize, 2); })); diff --git a/src/core/course/providers/module-prefetch-delegate.ts b/src/core/course/providers/module-prefetch-delegate.ts index 917a7bc4f..a42d080c5 100644 --- a/src/core/course/providers/module-prefetch-delegate.ts +++ b/src/core/course/providers/module-prefetch-delegate.ts @@ -690,6 +690,36 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { return Promise.resolve(0); } + /** + * Gets the estimated total size of data stored for a module. This includes + * the files downloaded for it (getModuleDownloadedSize) and also the total + * size of web service requests stored for it. + * + * @param module Module to get the size. + * @param courseId Course ID the module belongs to. + * @return Promise resolved with the total size (0 if unknown) + */ + getModuleTotalSize(module: any, courseId: number): Promise { + return this.getModuleDownloadedSize(module, courseId).then((downloadedSize) => { + if (isNaN(downloadedSize)) { + downloadedSize = 0; + } + const handler = this.getPrefetchHandlerFor(module); + if (handler) { + const site = this.sitesProvider.getCurrentSite(); + + return site.getComponentCacheSize(handler.component, module.id).then((cachedSize) => { + return cachedSize + downloadedSize; + }); + } else { + // If there is no handler then we can't find out the component name. + // So we can't work out the cached size, so just return downloaded size. + + return downloadedSize; + } + }); + } + /** * Get module files. * From 069c402ba5f6f1009239b45113213544522b9eaf Mon Sep 17 00:00:00 2001 From: sam marshall Date: Wed, 26 Aug 2020 12:35:03 +0100 Subject: [PATCH 3/6] MOBILE-3188 Settings: Consistently show total size estimate for site Changes the two settings pages that show the size of a site (from the main menu, these are 'App settings / Space usage' and 'Preferences') so that they: a) do not show the number of cache entries (not very informative for end users) b) show an estimate for 'space usage' that includes the total size of data in ws_cache The space usage estimate is not perfect (it doesn't include the per-row overhead in the ws_cache table, or other cached data that can be deleted such as calendar events or user data) but it will probably be good enough, and I don't think the 'number of entries' things was helpful to anyone. --- src/classes/site.ts | 23 +++++++++++++++++++ src/core/settings/pages/site/site.html | 1 - .../pages/space-usage/space-usage.html | 2 -- src/core/settings/providers/helper.ts | 4 ++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/classes/site.ts b/src/classes/site.ts index 77f7e994f..8e8e4ffde 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -1384,6 +1384,29 @@ export class CoreSite { } } + /** + * Gets an approximation of the cache table usage of the site. + * + * Currently this is just the total length of the data fields in the cache table. + * + * @return Promise resolved with the total size of all data in the cache table (bytes) + */ + getCacheUsage(): Promise { + return this.db.getFieldSql('SELECT SUM(length(data)) FROM ' + CoreSite.WS_CACHE_TABLE); + } + + /** + * Gets a total of the file and cache usage. + * + * @return Promise with the total of getSpaceUsage and getCacheUsage + */ + async getTotalUsage(): Promise { + const space = await this.getSpaceUsage(); + const cache = await this.getCacheUsage(); + + return space + cache; + } + /** * Returns the URL to the documentation of the app, based on Moodle version and current language. * diff --git a/src/core/settings/pages/site/site.html b/src/core/settings/pages/site/site.html index 6c932d246..e03a107a1 100644 --- a/src/core/settings/pages/site/site.html +++ b/src/core/settings/pages/site/site.html @@ -33,7 +33,6 @@

{{ 'core.settings.spaceusage' | translate }}

{{ spaceUsage.spaceUsage | coreBytesToSize }}

-

{{ 'core.settings.entriesincache' | translate: { $a: spaceUsage.cacheEntries } }}

diff --git a/src/core/settings/pages/space-usage/space-usage.html b/src/core/settings/pages/space-usage/space-usage.html index 29dac4705..914cb1f9b 100644 --- a/src/core/settings/pages/space-usage/space-usage.html +++ b/src/core/settings/pages/space-usage/space-usage.html @@ -20,7 +20,6 @@

{{ site.fullName }}

{{ site.spaceUsage | coreBytesToSize }}

-

{{ 'core.settings.entriesincache' | translate: { $a: site.cacheEntries } }}