diff --git a/packages/nocodb/src/lib/noco/NcProjectBuilderEE.ts b/packages/nocodb/src/lib/noco/NcProjectBuilderEE.ts index 9c287e3978..eb763f974f 100644 --- a/packages/nocodb/src/lib/noco/NcProjectBuilderEE.ts +++ b/packages/nocodb/src/lib/noco/NcProjectBuilderEE.ts @@ -36,7 +36,7 @@ export default class NcProjectBuilderEE extends NcProjectBuilder { break; case 'tableMetaCreate': // await curBuilder.onTableCreate(data.req.args.tn) - await curBuilder.xcTablesPopulate({tableNames: data.req.args.tableNames.map(tn => ({tn}))}); + await curBuilder.xcTablesPopulate({tableNames: data.req.args.tableNames.map(tn => ({tn})), type:'table'}); break; case 'viewMetaCreate': diff --git a/packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts b/packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts index 10a4ce2af4..582b93c98a 100644 --- a/packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts +++ b/packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts @@ -710,7 +710,6 @@ export default abstract class BaseApiBuilder implements XcDynami this.baseLog(`onTableUpdate : Generating model instance for '%s' table`, tn) - await NcHelp.executeOperations(aclOper, this.connectionConfig.client); @@ -910,11 +909,17 @@ export default abstract class BaseApiBuilder implements XcDynami childMeta.manyToMany = childMeta.manyToMany.filter(mm => !(mm.tn === parent && mm.rtn === child || mm.tn === child && mm.rtn === parent)) // filter lookup and relation virtual columns - parentMeta.v = parentMeta.v.filter(({mm, ...rest}) => (!mm || !(mm.tn === parent && mm.rtn === child || mm.tn === child && mm.rtn === parent)) + parentMeta.v = parentMeta.v.filter(({ + mm, + ...rest + }) => (!mm || !(mm.tn === parent && mm.rtn === child || mm.tn === child && mm.rtn === parent)) // check for lookup && !(rest.lk && rest.lk.type === 'mm' && (rest.lk.tn === parent && rest.lk.rtn === child || rest.lk.tn === child && rest.lk.rtn === parent)) ) - childMeta.v = childMeta.v.filter(({mm, ...rest}) => (!mm || !(mm.tn === parent && mm.rtn === child || mm.tn === child && mm.rtn === parent)) + childMeta.v = childMeta.v.filter(({ + mm, + ...rest + }) => (!mm || !(mm.tn === parent && mm.rtn === child || mm.tn === child && mm.rtn === parent)) // check for lookup && !(rest.lk && rest.lk.type === 'mm' && (rest.lk.tn === parent && rest.lk.rtn === child || rest.lk.tn === child && rest.lk.rtn === parent)) ) @@ -952,17 +957,17 @@ export default abstract class BaseApiBuilder implements XcDynami protected initDbDriver(): void { - this.dbDriver = NcConnectionMgr.get({ - dbAlias:this.dbAlias, - env:this.config.env, - config:this.config, - projectId:this.projectId + this.dbDriver = NcConnectionMgr.get({ + dbAlias: this.dbAlias, + env: this.config.env, + config: this.config, + projectId: this.projectId }); this.sqlClient = NcConnectionMgr.getSqlClient({ - dbAlias:this.dbAlias, - env:this.config.env, - config:this.config, - projectId:this.projectId + dbAlias: this.dbAlias, + env: this.config.env, + config: this.config, + projectId: this.projectId }) // if (!this.dbDriver) { // if(this.projectBuilder?.prefix){ @@ -1092,10 +1097,16 @@ export default abstract class BaseApiBuilder implements XcDynami return ctx; } - protected getTableNameAlias(tn: string) { + protected getTableNameAlias(tableName: string) { + let tn = tableName; if (this.metas?.[tn]?._tn) { return this.metas?.[tn]?._tn; } + + if (this.projectBuilder?.prefix) { + tn = tn.replace(this.projectBuilder?.prefix, '') + } + const modifiedTableName = tn?.replace(/^(?=\d+)/, 'ISN___') return this.getInflectedName(modifiedTableName, this.connectionConfig?.meta?.inflection?.tn); } @@ -1104,8 +1115,8 @@ export default abstract class BaseApiBuilder implements XcDynami this.baseLog(`generateContextForHasMany : '%s' => '%s'`, ctx.tn, tnc); return { ...ctx, - _tn: this.metas[ctx.tn]._tn, - _ctn: this.metas[tnc]._tn, + _tn: this.metas[ctx.tn]?._tn, + _ctn: this.metas[tnc]?._tn, ctn: tnc, project_id: this.projectId }; @@ -1426,10 +1437,10 @@ export default abstract class BaseApiBuilder implements XcDynami // todo: ignore duplicate m2m relations // todo: optimize, just compare associative table(Vtn) ...meta.manyToMany.filter((v, i) => !meta.v.some(v1 => v1.mm - && ( - v1.mm.tn === v.tn && v.rtn === v1.mm.rtn - || v1.mm.rtn === v.tn && v.tn === v1.mm.rtn - ) && v.vtn === v1.mm.vtn) + && ( + v1.mm.tn === v.tn && v.rtn === v1.mm.rtn + || v1.mm.rtn === v.tn && v.tn === v1.mm.rtn + ) && v.vtn === v1.mm.vtn) // ignore duplicate && !meta.manyToMany.some((v1, i1) => i1 !== i && v1.tn === v.tn && v.rtn === v1.rtn && v.vtn === v1.vtn) ).map(mm => { diff --git a/packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts b/packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts index 48bcebafc4..3152497a6a 100644 --- a/packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts +++ b/packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts @@ -238,7 +238,13 @@ export class GqlApiBuilder extends BaseApiBuilder implements XcMetaMgr { // todo: load procedure and functions await this.loadXcAcl(); - const {metaArr, enabledModels, tableAndViewArr, functionArr, procedureArr} = await this.readXcModelsAndGroupByType(); + const { + metaArr, + enabledModels, + tableAndViewArr, + functionArr, + procedureArr + } = await this.readXcModelsAndGroupByType(); const procedureResolver = new GqlProcedureResolver(this, functionArr, procedureArr, this.procedureOrFunctionAcls); @@ -286,12 +292,18 @@ export class GqlApiBuilder extends BaseApiBuilder implements XcMetaMgr { }; this.schemas[meta.title] = meta.schema; - this.policies[meta.title] = resolversArr.filter(({title}) => title === meta.title).reduce((aclObj, {acl, resolver}) => { + this.policies[meta.title] = resolversArr.filter(({title}) => title === meta.title).reduce((aclObj, { + acl, + resolver + }) => { aclObj[resolver] = JSON.parse(acl); return aclObj; }, {}); - const functions = resolversArr.filter(({title}) => title === meta.title).reduce((fnObj, {functions, resolver}) => { + const functions = resolversArr.filter(({title}) => title === meta.title).reduce((fnObj, { + functions, + resolver + }) => { fnObj[resolver] = JSON.parse(functions); return fnObj; }, {}); @@ -536,20 +548,32 @@ export class GqlApiBuilder extends BaseApiBuilder implements XcMetaMgr { if (args?.tableNames?.length) { + const relatedTableList = [] + // extract tables which have relation with the tables in list + for (const r of relations) { + if (args.tableNames.some(t => t.tn === r.tn)) { + if (!relatedTableList.includes(r.rtn)) { + relatedTableList.push(r.rtn) + await this.onTableDelete(r.rtn) + } + } else if (args.tableNames.some(t => t.tn === r.rtn)) { + if (!relatedTableList.includes(r.tn)) { + relatedTableList.push(r.tn) + await this.onTableDelete(r.tn) + } + } + } + tables = args.tableNames.map(({tn, _tn}) => ({ tn, _tn, type: args.type })); + + tables.push(...relatedTableList.map(t => ({tn: t}))) } else { tables = (await this.sqlClient.tableList())?.data?.list?.filter(({tn}) => !IGNORE_TABLES.includes(tn)); - /* filter based on prefix */ - if (this.projectBuilder?.prefix) { - tables = tables.filter(t => t.tn.startsWith(this.projectBuilder?.prefix)) - } - - this.tablesCount = tables.length; // enable extra // tables.push(...(await this.sqlClient.viewList())?.data?.list?.map(v => { // this.viewsCount++; @@ -607,6 +631,17 @@ export class GqlApiBuilder extends BaseApiBuilder implements XcMetaMgr { } + /* filter based on prefix */ + if (this.projectBuilder?.prefix) { + tables = tables.filter(t => { + t._tn = t._tn || t.tn.replace(this.projectBuilder?.prefix, '') + return t.tn.startsWith(this.projectBuilder?.prefix) + }) + } + + this.tablesCount = tables.length; + + if (tables.length) { relations.forEach(rel => rel.enabled = true); diff --git a/packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts b/packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts index f5ec2d9d5d..0d4d8075e4 100644 --- a/packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts +++ b/packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts @@ -2964,6 +2964,11 @@ export default class NcMetaMgr { tables = (await sqlClient.tableList())?.data?.list?.map(table => { return tables.find(mod => mod.title === table.tn) ?? {title: table.tn, alias: table.tn}; }); + const config = this.projectConfigs[this.getProjectId(args)] + tables = config?.prefix ? tables.filter(t => { + t.alias = t.title.replace(config?.prefix, '') + return t.title.startsWith(config?.prefix) + }) : tables; } const result = tables.reduce((obj, table) => { diff --git a/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts b/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts index c22784a0f5..4c313fe08e 100644 --- a/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts +++ b/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts @@ -314,16 +314,11 @@ export class RestApiBuilder extends BaseApiBuilder { } } - tables = args.tableNames.map(({tn}) => ({tn, type: args.type})); + tables = args.tableNames.map(({tn,_tn}) => ({tn, type: args.type,_tn})); + tables.push(...relatedTableList.map(t => ({tn:t}))) } else { tables = (await this.sqlClient.tableList())?.data?.list?.filter(({tn}) => !IGNORE_TABLES.includes(tn)); - /* filter based on prefix */ - if (this.projectBuilder?.prefix) { - tables = tables.filter(t => t?.tn?.startsWith(this.projectBuilder?.prefix)) - } - - this.tablesCount = tables.length; // enable extra /* tables.push(...(await this.sqlClient.viewList())?.data?.list?.map(v => { @@ -343,6 +338,17 @@ export class RestApiBuilder extends BaseApiBuilder { await this.populteProcedureAndFunctionRoutes(); } + + /* filter based on prefix */ + if (this.projectBuilder?.prefix) { + tables = tables.filter(t => { + t._tn = t._tn || t.tn.replace(this.projectBuilder?.prefix, '') + return t?.tn?.startsWith(this.projectBuilder?.prefix) + }) + } + + this.tablesCount = tables.length; + const relationRoutes: Array<() => Promise> = []; relations.forEach(r => {