diff --git a/packages/nocodb/src/lib/cache/CacheMgr.ts b/packages/nocodb/src/lib/cache/CacheMgr.ts index 258b1ff090..4a2303c4b9 100644 --- a/packages/nocodb/src/lib/cache/CacheMgr.ts +++ b/packages/nocodb/src/lib/cache/CacheMgr.ts @@ -4,7 +4,13 @@ export default abstract class CacheMgr { public abstract del(key: string): Promise; public abstract getAll(pattern: string): Promise; public abstract delAll(scope: string, pattern: string): Promise; - public abstract getList(scope: string, list: string[]): Promise; + public abstract getList( + scope: string, + list: string[] + ): Promise<{ + list: any[]; + isNoneList: boolean; + }>; public abstract setList( scope: string, subListKeys: string[], diff --git a/packages/nocodb/src/lib/cache/NocoCache.ts b/packages/nocodb/src/lib/cache/NocoCache.ts index 381760fef0..25fed59ea3 100644 --- a/packages/nocodb/src/lib/cache/NocoCache.ts +++ b/packages/nocodb/src/lib/cache/NocoCache.ts @@ -56,8 +56,15 @@ export default class NocoCache { public static async getList( scope: string, subKeys: string[] - ): Promise { - if (this.cacheDisabled) return Promise.resolve([]); + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { + if (this.cacheDisabled) + return Promise.resolve({ + list: [], + isNoneList: false, + }); return this.client.getList(scope, subKeys); } diff --git a/packages/nocodb/src/lib/cache/RedisCacheMgr.ts b/packages/nocodb/src/lib/cache/RedisCacheMgr.ts index b8deaae118..5fa6f24b69 100644 --- a/packages/nocodb/src/lib/cache/RedisCacheMgr.ts +++ b/packages/nocodb/src/lib/cache/RedisCacheMgr.ts @@ -114,7 +114,13 @@ export default class RedisCacheMgr extends CacheMgr { ); } - async getList(scope: string, subKeys: string[]): Promise { + async getList( + scope: string, + subKeys: string[] + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { // remove null from arrays subKeys = subKeys.filter((k) => k); // e.g. key = nc:::::list @@ -125,9 +131,22 @@ export default class RedisCacheMgr extends CacheMgr { // e.g. arr = ["nc:::", "nc:::"] const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; log(`RedisCacheMgr::getList: getting list with key ${key}`); - return Promise.all( - arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)) - ); + + const isNoneList = arr.length && arr[0] === 'NONE'; + + if (isNoneList) { + return Promise.resolve({ + list: [], + isNoneList, + }); + } + + return { + list: await Promise.all( + arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)) + ), + isNoneList, + }; } async setList( @@ -144,8 +163,8 @@ export default class RedisCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; if (!list.length) { - log(`RedisCacheMgr::setList: List is empty for ${listKey}. Skipping ...`); - return Promise.resolve(true); + // Set NONE here so that it won't hit the DB on each page load + return this.set(listKey, ['NONE']); } // fetch existing list const listOfGetKeys = @@ -225,7 +244,11 @@ export default class RedisCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; log(`RedisCacheMgr::appendToList: append key ${key} to ${listKey}`); - const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + if (list.length && list[0] === 'NONE') { + list = []; + await this.del(listKey); + } list.push(key); return this.set(listKey, list); } diff --git a/packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts b/packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts index a06ddd9fe5..831d650429 100644 --- a/packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts +++ b/packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts @@ -2,6 +2,7 @@ import debug from 'debug'; import Redis from 'ioredis-mock'; import { CacheDelDirection, CacheGetType, CacheScope } from '../utils/globals'; import CacheMgr from './CacheMgr'; + const log = debug('nc:cache'); export default class RedisMockCacheMgr extends CacheMgr { @@ -102,10 +103,9 @@ export default class RedisMockCacheMgr extends CacheMgr { `RedisMockCacheMgr::delAll: deleting all keys with pattern ${this.prefix}:${scope}:${pattern}` ); await Promise.all( - keys.map( - async (k) => - await this.deepDel(scope, k, CacheDelDirection.CHILD_TO_PARENT) - ) + keys.map(async (k) => { + await this.deepDel(scope, k, CacheDelDirection.CHILD_TO_PARENT); + }) ); return Promise.all( keys.map(async (k) => { @@ -114,7 +114,13 @@ export default class RedisMockCacheMgr extends CacheMgr { ); } - async getList(scope: string, subKeys: string[]): Promise { + async getList( + scope: string, + subKeys: string[] + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { // remove null from arrays subKeys = subKeys.filter((k) => k); // e.g. key = nc:::::list @@ -125,9 +131,21 @@ export default class RedisMockCacheMgr extends CacheMgr { // e.g. arr = ["nc:::", "nc:::"] const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; log(`RedisMockCacheMgr::getList: getting list with key ${key}`); - return Promise.all( - arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)) - ); + const isNoneList = arr.length && arr[0] === 'NONE'; + + if (isNoneList) { + return Promise.resolve({ + list: [], + isNoneList, + }); + } + + return { + list: await Promise.all( + arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)) + ), + isNoneList, + }; } async setList( @@ -144,10 +162,8 @@ export default class RedisMockCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; if (!list.length) { - log( - `RedisMockCacheMgr::setList: List is empty for ${listKey}. Skipping ...` - ); - return Promise.resolve(true); + // Set NONE here so that it won't hit the DB on each page load + return this.set(listKey, ['NONE']); } // fetch existing list const listOfGetKeys = @@ -227,7 +243,11 @@ export default class RedisMockCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; log(`RedisMockCacheMgr::appendToList: append key ${key} to ${listKey}`); - const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + if (list.length && list[0] === 'NONE') { + list = []; + await this.del(listKey); + } list.push(key); return this.set(listKey, list); } diff --git a/packages/nocodb/src/lib/models/Base.ts b/packages/nocodb/src/lib/models/Base.ts index 709f6598c0..bfd29c18fb 100644 --- a/packages/nocodb/src/lib/models/Base.ts +++ b/packages/nocodb/src/lib/models/Base.ts @@ -150,10 +150,12 @@ export default class Base implements BaseType { args: { projectId: string }, ncMeta = Noco.ncMeta ): Promise { - let baseDataList = await NocoCache.getList(CacheScope.BASE, [ + const cachedList = await NocoCache.getList(CacheScope.BASE, [ args.projectId, ]); - if (!baseDataList.length) { + let { list: baseDataList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !baseDataList.length) { baseDataList = await ncMeta.metaList2( args.projectId, null, diff --git a/packages/nocodb/src/lib/models/Column.ts b/packages/nocodb/src/lib/models/Column.ts index 5550142f2c..51b4e60d47 100644 --- a/packages/nocodb/src/lib/models/Column.ts +++ b/packages/nocodb/src/lib/models/Column.ts @@ -474,8 +474,12 @@ export default class Column implements ColumnType { }, ncMeta = Noco.ncMeta ): Promise { - let columnsList = await NocoCache.getList(CacheScope.COLUMN, [fk_model_id]); - if (!columnsList.length) { + const cachedList = await NocoCache.getList(CacheScope.COLUMN, [ + fk_model_id, + ]); + let { list: columnsList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !columnsList.length) { columnsList = await ncMeta.metaList2(null, null, MetaTable.COLUMNS, { condition: { fk_model_id, @@ -627,8 +631,10 @@ export default class Column implements ColumnType { // get lookup columns and delete { - let lookups = await NocoCache.getList(CacheScope.COL_LOOKUP, [id]); - if (!lookups.length) { + const cachedList = await NocoCache.getList(CacheScope.COL_LOOKUP, [id]); + let { list: lookups } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !lookups.length) { lookups = await ncMeta.metaList2(null, null, MetaTable.COL_LOOKUP, { condition: { fk_lookup_column_id: id }, }); @@ -640,8 +646,10 @@ export default class Column implements ColumnType { // get rollup column and delete { - let rollups = await NocoCache.getList(CacheScope.COL_ROLLUP, [id]); - if (!rollups.length) { + const cachedList = await NocoCache.getList(CacheScope.COL_ROLLUP, [id]); + let { list: rollups } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !rollups.length) { rollups = await ncMeta.metaList2(null, null, MetaTable.COL_ROLLUP, { condition: { fk_rollup_column_id: id }, }); @@ -652,10 +660,12 @@ export default class Column implements ColumnType { } { - let formulaColumns = await NocoCache.getList(CacheScope.COLUMN, [ + const cachedList = await NocoCache.getList(CacheScope.COLUMN, [ col.fk_model_id, ]); - if (!formulaColumns.length) { + let { list: formulaColumns } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !formulaColumns.length) { formulaColumns = await ncMeta.metaList2(null, null, MetaTable.COLUMNS, { condition: { fk_model_id: col.fk_model_id, @@ -682,33 +692,43 @@ export default class Column implements ColumnType { // if relation column check lookup and rollup and delete if (col.uidt === UITypes.LinkToAnotherRecord) { - // get lookup columns using relation and delete - let lookups = await NocoCache.getList(CacheScope.COL_LOOKUP, [id]); - if (!lookups.length) { - lookups = await ncMeta.metaList2(null, null, MetaTable.COL_LOOKUP, { - condition: { fk_relation_column_id: id }, - }); - } - for (const lookup of lookups) { - await Column.delete(lookup.fk_column_id, ncMeta); + { + // get lookup columns using relation and delete + const cachedList = await NocoCache.getList(CacheScope.COL_LOOKUP, [id]); + let { list: lookups } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !lookups.length) { + lookups = await ncMeta.metaList2(null, null, MetaTable.COL_LOOKUP, { + condition: { fk_relation_column_id: id }, + }); + } + for (const lookup of lookups) { + await Column.delete(lookup.fk_column_id, ncMeta); + } } - // get rollup columns using relation and delete - let rollups = await NocoCache.getList(CacheScope.COL_ROLLUP, [id]); - if (!rollups.length) { - rollups = await ncMeta.metaList2(null, null, MetaTable.COL_ROLLUP, { - condition: { fk_relation_column_id: id }, - }); - } - for (const rollup of rollups) { - await Column.delete(rollup.fk_column_id, ncMeta); + { + // get rollup columns using relation and delete + const cachedList = await NocoCache.getList(CacheScope.COL_ROLLUP, [id]); + let { list: rollups } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !rollups.length) { + rollups = await ncMeta.metaList2(null, null, MetaTable.COL_ROLLUP, { + condition: { fk_relation_column_id: id }, + }); + } + for (const rollup of rollups) { + await Column.delete(rollup.fk_column_id, ncMeta); + } } } // delete sorts { - let sorts = await NocoCache.getList(CacheScope.SORT, [id]); - if (!sorts.length) { + const cachedList = await NocoCache.getList(CacheScope.SORT, [id]); + let { list: sorts } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !sorts.length) { sorts = await ncMeta.metaList2(null, null, MetaTable.SORT, { condition: { fk_column_id: id, @@ -721,8 +741,10 @@ export default class Column implements ColumnType { } // delete filters { - let filters = await NocoCache.getList(CacheScope.FILTER_EXP, [id]); - if (!filters.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [id]); + let { list: filters } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filters.length) { filters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_column_id: id, diff --git a/packages/nocodb/src/lib/models/Filter.ts b/packages/nocodb/src/lib/models/Filter.ts index abb9b21b1a..54d5d3c4e6 100644 --- a/packages/nocodb/src/lib/models/Filter.ts +++ b/packages/nocodb/src/lib/models/Filter.ts @@ -326,10 +326,12 @@ export default class Filter implements FilterType { public async getChildren(ncMeta = Noco.ncMeta): Promise { if (this.children) return this.children; if (!this.is_group) return null; - let childFilters = await NocoCache.getList(CacheScope.FILTER_EXP, [ + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ this.id, ]); - if (!childFilters.length) { + let { list: childFilters } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !childFilters.length) { childFilters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_parent_id: this.id, @@ -369,10 +371,12 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta ): Promise { - let filters = await NocoCache.getList(CacheScope.FILTER_EXP, [ + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ viewId || hookId, ]); - if (!filters.length) { + let { list: filters } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filters.length) { filters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: viewId ? { fk_view_id: viewId } : { fk_hook_id: hookId }, orderBy: { @@ -480,8 +484,10 @@ export default class Filter implements FilterType { { viewId }: { viewId: any }, ncMeta = Noco.ncMeta ) { - let filterObjs = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); - if (!filterObjs.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + let { list: filterObjs } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filterObjs.length) { filterObjs = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_view_id: viewId }, orderBy: { @@ -499,8 +505,10 @@ export default class Filter implements FilterType { { hookId }: { hookId: any }, ncMeta = Noco.ncMeta ) { - let filterObjs = await NocoCache.getList(CacheScope.FILTER_EXP, [hookId]); - if (!filterObjs.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [hookId]); + let { list: filterObjs } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filterObjs.length) { filterObjs = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_hook_id: hookId }, orderBy: { @@ -520,8 +528,12 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta ) { - let filterObjs = await NocoCache.getList(CacheScope.FILTER_EXP, [parentId]); - if (!filterObjs.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ + parentId, + ]); + let { list: filterObjs } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filterObjs.length) { filterObjs = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_parent_id: parentId, @@ -546,11 +558,13 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta ) { - let filterObjs = await NocoCache.getList(CacheScope.FILTER_EXP, [ + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ hookId, parentId, ]); - if (!filterObjs.length) { + let { list: filterObjs } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filterObjs.length) { filterObjs = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_parent_id: parentId, diff --git a/packages/nocodb/src/lib/models/FormViewColumn.ts b/packages/nocodb/src/lib/models/FormViewColumn.ts index 69795004d1..06ff209fda 100644 --- a/packages/nocodb/src/lib/models/FormViewColumn.ts +++ b/packages/nocodb/src/lib/models/FormViewColumn.ts @@ -100,13 +100,11 @@ export default class FormViewColumn implements FormColumnType { await NocoCache.set(`${CacheScope.FORM_VIEW_COLUMN}:${fk_column_id}`, id); // if cache is not present skip pushing it into the list to avoid unexpected behaviour - if ( - ( - await NocoCache.getList(CacheScope.FORM_VIEW_COLUMN, [ - column.fk_view_id, - ]) - )?.length - ) + const { list } = await NocoCache.getList(CacheScope.FORM_VIEW_COLUMN, [ + column.fk_view_id, + ]); + + if (list?.length) await NocoCache.appendToList( CacheScope.FORM_VIEW_COLUMN, [column.fk_view_id], @@ -119,10 +117,12 @@ export default class FormViewColumn implements FormColumnType { viewId: string, ncMeta = Noco.ncMeta ): Promise { - let viewColumns = await NocoCache.getList(CacheScope.FORM_VIEW_COLUMN, [ + const cachedList = await NocoCache.getList(CacheScope.FORM_VIEW_COLUMN, [ viewId, ]); - if (!viewColumns.length) { + let { list: viewColumns } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !viewColumns.length) { viewColumns = await ncMeta.metaList2( null, null, diff --git a/packages/nocodb/src/lib/models/GalleryViewColumn.ts b/packages/nocodb/src/lib/models/GalleryViewColumn.ts index 6e744e0281..d20bb881e5 100644 --- a/packages/nocodb/src/lib/models/GalleryViewColumn.ts +++ b/packages/nocodb/src/lib/models/GalleryViewColumn.ts @@ -79,13 +79,11 @@ export default class GalleryViewColumn { ); // if cache is not present skip pushing it into the list to avoid unexpected behaviour - if ( - ( - await NocoCache.getList(CacheScope.GALLERY_VIEW_COLUMN, [ - column.fk_view_id, - ]) - )?.length - ) + const { list } = await NocoCache.getList(CacheScope.GALLERY_VIEW_COLUMN, [ + column.fk_view_id, + ]); + + if (list?.length) await NocoCache.appendToList( CacheScope.GALLERY_VIEW_COLUMN, [column.fk_view_id], @@ -99,10 +97,12 @@ export default class GalleryViewColumn { viewId: string, ncMeta = Noco.ncMeta ): Promise { - let views = await NocoCache.getList(CacheScope.GALLERY_VIEW_COLUMN, [ + const cachedList = await NocoCache.getList(CacheScope.GALLERY_VIEW_COLUMN, [ viewId, ]); - if (!views.length) { + let { list: views } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !views.length) { views = await ncMeta.metaList2( null, null, diff --git a/packages/nocodb/src/lib/models/GridViewColumn.ts b/packages/nocodb/src/lib/models/GridViewColumn.ts index 1c81d33e34..8bd0497f56 100644 --- a/packages/nocodb/src/lib/models/GridViewColumn.ts +++ b/packages/nocodb/src/lib/models/GridViewColumn.ts @@ -24,8 +24,12 @@ export default class GridViewColumn implements GridColumnType { viewId: string, ncMeta = Noco.ncMeta ): Promise { - let views = await NocoCache.getList(CacheScope.GRID_VIEW_COLUMN, [viewId]); - if (!views.length) { + const cachedList = await NocoCache.getList(CacheScope.GRID_VIEW_COLUMN, [ + viewId, + ]); + let { list: views } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !views.length) { views = await ncMeta.metaList2(null, null, MetaTable.GRID_VIEW_COLUMNS, { condition: { fk_view_id: viewId, @@ -99,13 +103,10 @@ export default class GridViewColumn implements GridColumnType { await NocoCache.set(`${CacheScope.GRID_VIEW_COLUMN}:${fk_column_id}`, id); // if cache is not present skip pushing it into the list to avoid unexpected behaviour - if ( - ( - await NocoCache.getList(CacheScope.GRID_VIEW_COLUMN, [ - column.fk_view_id, - ]) - )?.length - ) + const { list } = await NocoCache.getList(CacheScope.GRID_VIEW_COLUMN, [ + column.fk_view_id, + ]); + if (list.length) await NocoCache.appendToList( CacheScope.GRID_VIEW_COLUMN, [column.fk_view_id], diff --git a/packages/nocodb/src/lib/models/Hook.ts b/packages/nocodb/src/lib/models/Hook.ts index 1b0e0761a3..aeef9e96a0 100644 --- a/packages/nocodb/src/lib/models/Hook.ts +++ b/packages/nocodb/src/lib/models/Hook.ts @@ -85,8 +85,12 @@ export default class Hook implements HookType { }, ncMeta = Noco.ncMeta ) { - let hooks = await NocoCache.getList(CacheScope.HOOK, [param.fk_model_id]); - if (!hooks.length) { + const cachedList = await NocoCache.getList(CacheScope.HOOK, [ + param.fk_model_id, + ]); + let { list: hooks } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !hooks.length) { hooks = await ncMeta.metaList(null, null, MetaTable.HOOKS, { condition: { fk_model_id: param.fk_model_id, diff --git a/packages/nocodb/src/lib/models/HookFilter.ts b/packages/nocodb/src/lib/models/HookFilter.ts index b9b66fb8f3..4f3bdb2488 100644 --- a/packages/nocodb/src/lib/models/HookFilter.ts +++ b/packages/nocodb/src/lib/models/HookFilter.ts @@ -205,10 +205,12 @@ export default class Filter { public async getChildren(ncMeta = Noco.ncMeta): Promise { if (this.children) return this.children; if (!this.is_group) return null; - let childFilters = await NocoCache.getList(CacheScope.FILTER_EXP, [ + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ this.id, ]); - if (!childFilters.length) { + let { list: childFilters } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !childFilters.length) { childFilters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_parent_id: this.id, @@ -243,8 +245,10 @@ export default class Filter { }, ncMeta = Noco.ncMeta ): Promise { - let filters = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); - if (!filters.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + let { list: filters } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filters.length) { filters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_view_id: viewId }, }); @@ -327,8 +331,10 @@ export default class Filter { { viewId }: { viewId: any }, ncMeta = Noco.ncMeta ) { - let filterObjs = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); - if (!filterObjs.length) { + const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + let { list: filterObjs } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !filterObjs.length) { filterObjs = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP, { condition: { fk_view_id: viewId }, }); diff --git a/packages/nocodb/src/lib/models/KanbanViewColumn.ts b/packages/nocodb/src/lib/models/KanbanViewColumn.ts index 71e58954dd..cea673e14d 100644 --- a/packages/nocodb/src/lib/models/KanbanViewColumn.ts +++ b/packages/nocodb/src/lib/models/KanbanViewColumn.ts @@ -85,10 +85,12 @@ export default class KanbanViewColumn implements KanbanColumnType { viewId: string, ncMeta = Noco.ncMeta ): Promise { - let views = await NocoCache.getList(CacheScope.KANBAN_VIEW_COLUMN, [ + const cachedList = await NocoCache.getList(CacheScope.KANBAN_VIEW_COLUMN, [ viewId, ]); - if (!views.length) { + let { list: views } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !views.length) { views = await ncMeta.metaList2( null, null, diff --git a/packages/nocodb/src/lib/models/MapViewColumn.ts b/packages/nocodb/src/lib/models/MapViewColumn.ts index a5781bf1df..3d38af9e5d 100644 --- a/packages/nocodb/src/lib/models/MapViewColumn.ts +++ b/packages/nocodb/src/lib/models/MapViewColumn.ts @@ -67,10 +67,10 @@ export default class MapViewColumn { await NocoCache.set(`${CacheScope.MAP_VIEW_COLUMN}:${fk_column_id}`, id); // if cache is not present skip pushing it into the list to avoid unexpected behaviour - if ( - (await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [column.fk_view_id])) - ?.length - ) + const { list } = await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [ + column.fk_view_id, + ]); + if (list?.length) await NocoCache.appendToList( CacheScope.MAP_VIEW_COLUMN, [column.fk_view_id], @@ -84,8 +84,12 @@ export default class MapViewColumn { viewId: string, ncMeta = Noco.ncMeta ): Promise { - let views = await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [viewId]); - if (!views.length) { + const cachedList = await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [ + viewId, + ]); + let { list: views } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !views.length) { views = await ncMeta.metaList2(null, null, MetaTable.MAP_VIEW_COLUMNS, { condition: { fk_view_id: viewId, diff --git a/packages/nocodb/src/lib/models/Model.ts b/packages/nocodb/src/lib/models/Model.ts index bd69c4df9b..abfea84ef9 100644 --- a/packages/nocodb/src/lib/models/Model.ts +++ b/packages/nocodb/src/lib/models/Model.ts @@ -160,13 +160,10 @@ export default class Model implements TableType { }, ncMeta = Noco.ncMeta ): Promise { - let modelList = []; - if (base_id) { - await NocoCache.getList(CacheScope.MODEL, [project_id, base_id]); - } else { - await NocoCache.getList(CacheScope.MODEL, [project_id]); - } - if (!modelList.length) { + const cachedList = await NocoCache.getList(CacheScope.MODEL, [project_id]); + let { list: modelList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !modelList.length) { modelList = await ncMeta.metaList2( project_id, base_id, @@ -183,15 +180,7 @@ export default class Model implements TableType { model.meta = parseMetaProp(model); } - if (base_id) { - await NocoCache.setList( - CacheScope.MODEL, - [project_id, base_id], - modelList - ); - } else { - await NocoCache.setList(CacheScope.MODEL, [project_id], modelList); - } + await NocoCache.setList(CacheScope.MODEL, [project_id], modelList); } modelList.sort( (a, b) => @@ -211,11 +200,13 @@ export default class Model implements TableType { }, ncMeta = Noco.ncMeta ): Promise { - let modelList = await NocoCache.getList(CacheScope.MODEL, [ + const cachedList = await NocoCache.getList(CacheScope.MODEL, [ project_id, db_alias, ]); - if (!modelList.length) { + let { list: modelList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !modelList.length) { modelList = await ncMeta.metaList2( project_id, db_alias, diff --git a/packages/nocodb/src/lib/models/ModelRoleVisibility.ts b/packages/nocodb/src/lib/models/ModelRoleVisibility.ts index 7813a94171..724ecaf07b 100644 --- a/packages/nocodb/src/lib/models/ModelRoleVisibility.ts +++ b/packages/nocodb/src/lib/models/ModelRoleVisibility.ts @@ -24,10 +24,13 @@ export default class ModelRoleVisibility implements ModelRoleVisibilityType { } static async list(projectId): Promise { - let data = await NocoCache.getList(CacheScope.MODEL_ROLE_VISIBILITY, [ - projectId, - ]); - if (!data.length) { + const cachedList = await NocoCache.getList( + CacheScope.MODEL_ROLE_VISIBILITY, + [projectId] + ); + let { list: data } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !data.length) { data = await Noco.ncMeta.metaList2( projectId, null, diff --git a/packages/nocodb/src/lib/models/Plugin.ts b/packages/nocodb/src/lib/models/Plugin.ts index 5d88dc529e..1740853253 100644 --- a/packages/nocodb/src/lib/models/Plugin.ts +++ b/packages/nocodb/src/lib/models/Plugin.ts @@ -43,8 +43,10 @@ export default class Plugin implements PluginType { } static async list(ncMeta = Noco.ncMeta) { - let pluginList = await NocoCache.getList(CacheScope.PLUGIN, []); - if (!pluginList.length) { + const cachedList = await NocoCache.getList(CacheScope.PLUGIN, []); + let { list: pluginList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !pluginList.length) { pluginList = await ncMeta.metaList2(null, null, MetaTable.PLUGIN); await NocoCache.setList(CacheScope.PLUGIN, [], pluginList); } diff --git a/packages/nocodb/src/lib/models/Project.ts b/packages/nocodb/src/lib/models/Project.ts index a26ac98a08..b0058dc1ef 100644 --- a/packages/nocodb/src/lib/models/Project.ts +++ b/packages/nocodb/src/lib/models/Project.ts @@ -79,8 +79,10 @@ export default class Project implements ProjectType { ncMeta = Noco.ncMeta ): Promise { // todo: pagination - let projectList = await NocoCache.getList(CacheScope.PROJECT, []); - if (!projectList.length) { + const cachedList = await NocoCache.getList(CacheScope.PROJECT, []); + let { list: projectList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !projectList.length) { projectList = await ncMeta.metaList2(null, null, MetaTable.PROJECT, { xcCondition: { _or: [ diff --git a/packages/nocodb/src/lib/models/ProjectUser.ts b/packages/nocodb/src/lib/models/ProjectUser.ts index 1090a10c2e..c8171d045d 100644 --- a/packages/nocodb/src/lib/models/ProjectUser.ts +++ b/packages/nocodb/src/lib/models/ProjectUser.ts @@ -187,10 +187,12 @@ export default class ProjectUser { } // remove project from user project list cache - let cachedProjectList = await NocoCache.getList(CacheScope.USER_PROJECT, [ + const cachedList = await NocoCache.getList(CacheScope.USER_PROJECT, [ userId, ]); - if (cachedProjectList?.length) { + let { list: cachedProjectList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && cachedProjectList?.length) { cachedProjectList = cachedProjectList.filter((p) => p.id !== projectId); await NocoCache.setList( CacheScope.USER_PROJECT, @@ -221,11 +223,13 @@ export default class ProjectUser { ncMeta = Noco.ncMeta ): Promise { // todo: pagination - let projectList = await NocoCache.getList(CacheScope.USER_PROJECT, [ + const cachedList = await NocoCache.getList(CacheScope.USER_PROJECT, [ userId, ]); + let { list: projectList } = cachedList; + const { isNoneList } = cachedList; - if (projectList.length) { + if (!isNoneList && projectList.length) { return projectList; } diff --git a/packages/nocodb/src/lib/models/SelectOption.ts b/packages/nocodb/src/lib/models/SelectOption.ts index 4575168375..b1523aabbc 100644 --- a/packages/nocodb/src/lib/models/SelectOption.ts +++ b/packages/nocodb/src/lib/models/SelectOption.ts @@ -69,10 +69,12 @@ export default class SelectOption implements SelectOptionType { } public static async read(fk_column_id: string, ncMeta = Noco.ncMeta) { - let options = await NocoCache.getList(CacheScope.COL_SELECT_OPTION, [ + const cachedList = await NocoCache.getList(CacheScope.COL_SELECT_OPTION, [ fk_column_id, ]); - if (!options.length) { + let { list: options } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !options.length) { options = await ncMeta.metaList2( null, //, null, //model.db_alias, diff --git a/packages/nocodb/src/lib/models/Sort.ts b/packages/nocodb/src/lib/models/Sort.ts index 375fa3d09e..7a020cde03 100644 --- a/packages/nocodb/src/lib/models/Sort.ts +++ b/packages/nocodb/src/lib/models/Sort.ts @@ -114,8 +114,10 @@ export default class Sort { ncMeta = Noco.ncMeta ): Promise { if (!viewId) return null; - let sortList = await NocoCache.getList(CacheScope.SORT, [viewId]); - if (!sortList.length) { + const cachedList = await NocoCache.getList(CacheScope.SORT, [viewId]); + let { list: sortList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !sortList.length) { sortList = await ncMeta.metaList2(null, null, MetaTable.SORT, { condition: { fk_view_id: viewId }, orderBy: { diff --git a/packages/nocodb/src/lib/models/View.ts b/packages/nocodb/src/lib/models/View.ts index 2e7f9374f1..6236d8c107 100644 --- a/packages/nocodb/src/lib/models/View.ts +++ b/packages/nocodb/src/lib/models/View.ts @@ -205,8 +205,10 @@ export default class View implements ViewType { } public static async list(modelId: string, ncMeta = Noco.ncMeta) { - let viewsList = await NocoCache.getList(CacheScope.VIEW, [modelId]); - if (!viewsList.length) { + const cachedList = await NocoCache.getList(CacheScope.VIEW, [modelId]); + let { list: viewsList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !viewsList.length) { viewsList = await ncMeta.metaList2(null, null, MetaTable.VIEWS, { condition: { fk_model_id: modelId, @@ -1123,8 +1125,10 @@ export default class View implements ViewType { ); // get existing cache - const dataList = await NocoCache.getList(scope, [viewId]); - if (dataList?.length) { + const cachedList = await NocoCache.getList(scope, [viewId]); + const { list: dataList } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && dataList?.length) { for (const o of dataList) { if (!ignoreColdIds?.length || !ignoreColdIds.includes(o.fk_column_id)) { // set data @@ -1209,7 +1213,9 @@ export default class View implements ViewType { } // get existing cache - const dataList = await NocoCache.getList(scope, [viewId]); + const cachedList = await NocoCache.getList(scope, [viewId]); + const { list: dataList } = cachedList; + const { isNoneList } = cachedList; const colsEssentialForView = view.type === ViewTypes.MAP @@ -1218,7 +1224,7 @@ export default class View implements ViewType { const mergedIgnoreColdIds = [...ignoreColdIds, ...colsEssentialForView]; - if (dataList?.length) { + if (!isNoneList && dataList?.length) { for (const o of dataList) { if ( !mergedIgnoreColdIds?.length || @@ -1257,8 +1263,10 @@ export default class View implements ViewType { } static async shareViewList(tableId, ncMeta = Noco.ncMeta) { - let sharedViews = await NocoCache.getList(CacheScope.VIEW, [tableId]); - if (!sharedViews.length) { + const cachedList = await NocoCache.getList(CacheScope.VIEW, [tableId]); + let { list: sharedViews } = cachedList; + const { isNoneList } = cachedList; + if (!isNoneList && !sharedViews.length) { sharedViews = await ncMeta.metaList2(null, null, MetaTable.VIEWS, { xcCondition: { fk_model_id: {