Browse Source

fix: update table alias rename

re #718

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/797/head
Pranav C 3 years ago
parent
commit
1a8b5ed6c9
  1. 70
      packages/nc-gui/components/ProjectTreeView.vue
  2. 21
      packages/nc-gui/layouts/default.vue
  3. 16
      packages/nocodb/src/lib/noco/NcProjectBuilder.ts
  4. 189
      packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts
  5. 82
      packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts
  6. 2
      packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts
  7. 12
      packages/nocodb/src/lib/noco/migrations/nc_001_init.ts
  8. 173
      packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts
  9. 2
      packages/nocodb/src/lib/sqlMgr/code/BaseRender.ts
  10. 2
      packages/nocodb/src/lib/sqlMgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts
  11. 2
      packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts

70
packages/nc-gui/components/ProjectTreeView.vue

@ -647,7 +647,7 @@
<script> <script>
/* eslint-disable */ /* eslint-disable */
import { mapMutations, mapGetters, mapActions } from 'vuex'; import {mapMutations, mapGetters, mapActions} from 'vuex';
import rightClickOptions from '../helpers/rightClickOptions'; import rightClickOptions from '../helpers/rightClickOptions';
import rightClickOptionsSub from '../helpers/rightClickOptionsSub'; import rightClickOptionsSub from '../helpers/rightClickOptionsSub';
@ -655,7 +655,7 @@ import icons from '../helpers/treeViewIcons';
import textDlgSubmitCancel from './utils/dlgTextSubmitCancel'; import textDlgSubmitCancel from './utils/dlgTextSubmitCancel';
import dlgLabelSubmitCancel from './utils/dlgLabelSubmitCancel'; import dlgLabelSubmitCancel from './utils/dlgLabelSubmitCancel';
import { copyTextToClipboard } from '../helpers/xutils'; import {copyTextToClipboard} from '../helpers/xutils';
import DlgTableCreate from '@/components/utils/dlgTableCreate'; import DlgTableCreate from '@/components/utils/dlgTableCreate';
import DlgViewCreate from '@/components/utils/dlgViewCreate'; import DlgViewCreate from '@/components/utils/dlgViewCreate';
import SponsorMini from '@/components/sponsorMini'; import SponsorMini from '@/components/sponsorMini';
@ -704,7 +704,7 @@ export default {
x: 0, x: 0,
y: 0, y: 0,
menuItem: null, menuItem: null,
menu: [{ title: 'Execute' }], menu: [{title: 'Execute'}],
icons, icons,
tree: [], tree: [],
active: [], active: [],
@ -742,7 +742,7 @@ export default {
defaultValue: null, defaultValue: null,
}, },
rolesList: null, rolesList: null,
selectedNodeForDelete: { dialog: false, item: null, heading: null }, selectedNodeForDelete: {dialog: false, item: null, heading: null},
}), }),
computed: { computed: {
previewAs: { previewAs: {
@ -845,8 +845,8 @@ export default {
this.changeActiveTab(tabIndex); this.changeActiveTab(tabIndex);
} else { } else {
console.log('add app store tab'); console.log('add app store tab');
let item = { name: 'App Store', key: `appStore` }; let item = {name: 'App Store', key: `appStore`};
item._nodes = { env: '_noco' }; item._nodes = {env: '_noco'};
item._nodes.type = 'appStore'; item._nodes.type = 'appStore';
this.$store.dispatch('tabs/ActAddTab', item); this.$store.dispatch('tabs/ActAddTab', item);
} }
@ -881,8 +881,8 @@ export default {
this.changeActiveTab(tabIndex); this.changeActiveTab(tabIndex);
} else { } else {
console.log('add roles tab'); console.log('add roles tab');
let item = { name: 'Team & Auth ', key: `roles` }; let item = {name: 'Team & Auth ', key: `roles`};
item._nodes = { env: '_noco' }; item._nodes = {env: '_noco'};
item._nodes.type = 'roles'; item._nodes.type = 'roles';
this.$store.dispatch('tabs/ActAddTab', item); this.$store.dispatch('tabs/ActAddTab', item);
} }
@ -893,8 +893,8 @@ export default {
this.changeActiveTab(tabIndex); this.changeActiveTab(tabIndex);
} else { } else {
console.log('add acl tab'); console.log('add acl tab');
let item = { name: 'Meta Management', key: `disableOrEnableModel` }; let item = {name: 'Meta Management', key: `disableOrEnableModel`};
item._nodes = { env: '_noco' }; item._nodes = {env: '_noco'};
item._nodes.type = 'disableOrEnableModel'; item._nodes.type = 'disableOrEnableModel';
this.$store.dispatch('tabs/ActAddTab', item); this.$store.dispatch('tabs/ActAddTab', item);
} }
@ -1008,7 +1008,7 @@ export default {
} }
if (item._nodes.type === 'table') { if (item._nodes.type === 'table') {
let tableIndex = +item._nodes.key.split('.').pop(); let tableIndex = +item._nodes.key.split('.').pop();
if (!(await this.$store.dispatch('windows/ActCheckMaxTable', { tableIndex }))) return; if (!(await this.$store.dispatch('windows/ActCheckMaxTable', {tableIndex}))) return;
} }
this.$store.dispatch('tabs/ActAddTab', item); this.$store.dispatch('tabs/ActAddTab', item);
} }
@ -1074,9 +1074,9 @@ export default {
if (!this.isTreeView) { if (!this.isTreeView) {
if (this.$route.query.type) { if (this.$route.query.type) {
const node = this.listViewArr.find(n => n.type === `${this.$route.query.type}Dir`); const node = this.listViewArr.find(n => n.type === `${this.$route.query.type}Dir`);
await this.addTab({ ...(node || this.listViewArr[0]) }, false, true); await this.addTab({...(node || this.listViewArr[0])}, false, true);
} else { } else {
await this.addTab({ ...this.listViewArr[0] }, false, true); await this.addTab({...this.listViewArr[0]}, false, true);
} }
} }
} catch (error) { } catch (error) {
@ -1234,7 +1234,7 @@ export default {
dbAlias: item._nodes.dbAlias, dbAlias: item._nodes.dbAlias,
}, },
func, func,
{ tn: item.name }, {tn: item.name},
]); ]);
if (result && result.data) { if (result && result.data) {
copyTextToClipboard(result.data, 'selection'); copyTextToClipboard(result.data, 'selection');
@ -1242,7 +1242,7 @@ export default {
copyTextToClipboard('Example String', 'selection'); copyTextToClipboard('Example String', 'selection');
} }
let sqlClientNode = { ...item._nodes }; let sqlClientNode = {...item._nodes};
let newItem = { let newItem = {
_nodes: sqlClientNode, _nodes: sqlClientNode,
}; };
@ -1272,20 +1272,22 @@ export default {
} }
}, },
async mtdDialogRenameTableSubmit(tn, cookie) { async mtdDialogRenameTableSubmit(_tn, cookie) {
console.log(tn);
let item = cookie; let item = cookie;
await this.$store.dispatch('sqlMgr/ActSqlOpPlus', [ await this.$store.dispatch(
{ // 'sqlMgr/ActSqlOpPlus',[
env: item._nodes.env, 'sqlMgr/ActSqlOp', [
dbAlias: item._nodes.dbAlias, {
}, env: item._nodes.env,
'tableRename', dbAlias: item._nodes.dbAlias,
{ },
tn: tn, // 'tableRename',
tn_old: item.name, 'ncTableAliasRename',
}, {
]); tn: _tn,
tn_old: item.name,
},
]);
await this.removeTabsByName(item); await this.removeTabsByName(item);
await this.loadTablesFromParentTreeNode({ await this.loadTablesFromParentTreeNode({
_nodes: { _nodes: {
@ -1296,14 +1298,15 @@ export default {
_nodes: { _nodes: {
env: this.menuItem._nodes.env, env: this.menuItem._nodes.env,
dbAlias: this.menuItem._nodes.dbAlias, dbAlias: this.menuItem._nodes.dbAlias,
tn: tn, tn: this.menuItem._nodes.tn,
_tn:_tn,
dbConnection: this.menuItem._nodes.dbConnection, dbConnection: this.menuItem._nodes.dbConnection,
type: 'table', type: 'table',
dbKey: this.menuItem._nodes.dbKey, dbKey: this.menuItem._nodes.dbKey,
key: this.menuItem._nodes.key, key: this.menuItem._nodes.key,
}, },
name: tn, name: _tn,
}); });
this.dialogRenameTable.dialogShow = false; this.dialogRenameTable.dialogShow = false;
this.dialogRenameTable.defaultValue = null; this.dialogRenameTable.defaultValue = null;
@ -1539,7 +1542,7 @@ export default {
dbAlias: item._nodes.dbAlias, dbAlias: item._nodes.dbAlias,
}, },
'tableDelete', 'tableDelete',
{ tn: item._nodes.tn, columns: columns.data.list } {tn: item._nodes.tn, columns: columns.data.list}
); );
await this.loadTablesFromParentTreeNode({ await this.loadTablesFromParentTreeNode({
_nodes: { _nodes: {
@ -1554,7 +1557,7 @@ export default {
dbAlias: item._nodes.dbAlias, dbAlias: item._nodes.dbAlias,
}, },
'viewRead', 'viewRead',
{ view_name: item._nodes.view_name }, {view_name: item._nodes.view_name},
]); ]);
await this.$store.dispatch('sqlMgr/ActSqlOpPlus', [ await this.$store.dispatch('sqlMgr/ActSqlOpPlus', [
@ -1657,7 +1660,8 @@ export default {
this.loadDefaultTabs(true); this.loadDefaultTabs(true);
this.loadRoles(); this.loadRoles();
}, },
beforeCreate() {}, beforeCreate() {
},
mounted() { mounted() {
// this.setBorderWidth(); // this.setBorderWidth();
// this.setEvents(); // this.setEvents();

21
packages/nc-gui/layouts/default.vue

@ -299,7 +299,7 @@
</v-icon> </v-icon>
</v-btn> </v-btn>
</template> </template>
<v-list dense> <v-list dense class="nc-user-menu">
<template v-if="isDocker"> <template v-if="isDocker">
<!-- <v-list-item @click="xcMetaTabAdd" v-ge="['Meta add','']">--> <!-- <v-list-item @click="xcMetaTabAdd" v-ge="['Meta add','']">-->
<!-- <v-list-item-title>--> <!-- <v-list-item-title>-->
@ -327,7 +327,7 @@
<v-list-item-title> <v-list-item-title>
<v-icon small> <v-icon small>
mdi-at mdi-at
</v-icon>&nbsp; <span class="font-weight-bold">{{ userEmail }}</span> </v-icon>&nbsp; <span class="font-weight-bold caption">{{ userEmail }}</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -343,7 +343,7 @@
<v-icon key="terminal-dash" small> <v-icon key="terminal-dash" small>
mdi-content-copy mdi-content-copy
</v-icon>&nbsp; </v-icon>&nbsp;
<span class="font-weight-regular">Copy auth token</span> <span class="font-weight-regular caption">Copy auth token</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -367,7 +367,7 @@
<v-icon key="terminal-dash" small> <v-icon key="terminal-dash" small>
{{ isGql ? 'mdi-graphql' : 'mdi-code-json' }} {{ isGql ? 'mdi-graphql' : 'mdi-code-json' }}
</v-icon>&nbsp; </v-icon>&nbsp;
<span class="font-weight-regular"> <span class="font-weight-regular caption">
{{ isGql ? 'GraphQL APIs' : 'Swagger APIs Doc' }}</span> {{ isGql ? 'GraphQL APIs' : 'Swagger APIs Doc' }}</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -376,7 +376,7 @@
<v-list-item-title> <v-list-item-title>
<v-icon small> <v-icon small>
mdi-information-outline mdi-information-outline
</v-icon>&nbsp; <span class="font-weight-regular">Copy Project info</span> </v-icon>&nbsp; <span class="font-weight-regular caption">Copy Project info</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -385,7 +385,7 @@
<v-icon key="terminal-dash" small> <v-icon key="terminal-dash" small>
mdi-palette mdi-palette
</v-icon>&nbsp; </v-icon>&nbsp;
<span class="font-weight-regular">Themes</span> <span class="font-weight-regular caption">Themes</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -395,7 +395,7 @@
<v-list-item-title> <v-list-item-title>
<v-icon small> <v-icon small>
mdi-logout mdi-logout
</v-icon>&nbsp; <span class="font-weight-regular">Sign Out</span> </v-icon>&nbsp; <span class="font-weight-regular caption">Sign Out</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
</template> </template>
@ -415,7 +415,7 @@
<v-icon small> <v-icon small>
mdi-account-plus-outline mdi-account-plus-outline
</v-icon> &nbsp; <span </v-icon> &nbsp; <span
class="font-weight-regular" class="font-weight-regular caption"
>Sign Up</span> >Sign Up</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
@ -423,7 +423,7 @@
<v-list-item-title> <v-list-item-title>
<v-icon small> <v-icon small>
mdi-login mdi-login
</v-icon> &nbsp; <span class="font-weight-regular">Login</span> </v-icon> &nbsp; <span class="font-weight-regular caption">Login</span>
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
<!-- <v-list-item @click="openPricingPage">--> <!-- <v-list-item @click="openPricingPage">-->
@ -1096,6 +1096,9 @@ a {
/deep/ .nc-ripple{ /deep/ .nc-ripple{
border-radius: 50%; border-radius: 50%;
} }
/deep/ .nc-user-menu .v-list-item--dense, /deep/ .nc-user-menu .v-list--dense .v-list-item{
min-height:30px
}
</style> </style>

16
packages/nocodb/src/lib/noco/NcProjectBuilder.ts

@ -255,6 +255,22 @@ export default class NcProjectBuilder {
console.log(`Updated routes for table : ${data.req.args.tn}`); console.log(`Updated routes for table : ${data.req.args.tn}`);
break; break;
case 'ncTableAliasRename':
await curBuilder.onTableAliasRename(
data.req.args.tn_old,
data.req.args.tn
);
this.app.ncMeta.audit(this.id, curBuilder.getDbAlias(), 'nc_audit', {
op_type: 'TABLE',
op_sub_type: 'RENAMED',
user: data.user.email,
description: `renamed table alias ${data.req.args.tn_old} to ${data.req.args.tn} `,
ip: data.ctx.req.clientIp
});
console.log(`Updated routes for table : ${data.req.args.tn}`);
break;
case 'xcRoutesHandlerUpdate': case 'xcRoutesHandlerUpdate':
case 'xcResolverHandlerUpdate': case 'xcResolverHandlerUpdate':
case 'xcRpcHandlerUpdate': case 'xcRpcHandlerUpdate':

189
packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts

@ -470,6 +470,179 @@ export default abstract class BaseApiBuilder<T extends Noco>
await this.modifyTableNameInACL(oldTableName, newTableName); await this.modifyTableNameInACL(oldTableName, newTableName);
} }
public async onTableAliasRename(
oldTableAliasName: string,
newTableAliasName: string
): Promise<any> {
this.baseLog(
`onTableAliasRename : '%s' => '%s'`,
oldTableAliasName,
newTableAliasName
);
this.baseLog(
`onTableAliasRename : updating table name in hooks meta table - '%s' => '%s'`,
oldTableAliasName,
newTableAliasName
);
const tableName =
this.getTableName(oldTableAliasName) ||
this.getTableName(newTableAliasName);
XcCache.del([this.projectId, this.dbAlias, 'table', tableName].join('::'));
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_relations',
{
_rtn: newTableAliasName
},
{
_rtn: oldTableAliasName
}
);
const meta = this.metas[tableName];
meta._tn = newTableAliasName;
if (oldTableAliasName === newTableAliasName) {
return;
}
// delete old model
delete this.models[tableName];
// todo: update virtual columns
// const rootPath = `/api/${ctx.routeVersionLetter}/${ctx._tn}`;
const relatedTableList = new Set<string>();
// update in hasMany
for (const hm of meta.hasMany || []) {
hm._rtn = newTableAliasName;
relatedTableList.add(hm.tn);
}
// update in belongsTo
for (const bt of meta.belongsTo || []) {
bt._tn = newTableAliasName;
relatedTableList.add(bt.rtn);
}
// update in MnyToMany
for (const mm of meta.manyToMany || []) {
mm._tn = newTableAliasName;
relatedTableList.add(mm.rtn);
}
for (const v of meta.v || []) {
if (v?.hm?._rtn) v.hm._rtn = newTableAliasName;
else if (v?.bt?._tn) v.bt._tn = newTableAliasName;
else if (v?.mm?._tn) v.mm._tn = newTableAliasName;
else if (v?.lk) {
if (v?.lk.type === 'hm') {
v.lk._rtn = newTableAliasName;
} else if (v?.lk.type === 'bt' || v.lk.type === 'mm') {
v.lk._tn = newTableAliasName;
}
} else if (v?.rl) {
if (v.rl === 'hm') {
v.rl._rtn = newTableAliasName;
} else if (v.rl.type === 'bt' || v.rl.type === 'mm') {
v.rl._tn = newTableAliasName;
}
}
// todo: lookup and rollup
}
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_relations',
{
_tn: newTableAliasName
},
{
_tn: oldTableAliasName
}
);
/* Update meta data */
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_models',
{
meta: JSON.stringify(meta),
alias: newTableAliasName
},
{ title: tableName, type: 'table' }
);
for (const relTableName of relatedTableList) {
const meta = this.getMeta(relTableName);
// update in hasMany
for (const hm of meta.hasMany || []) {
if (hm.tn !== tableName) continue;
hm._tn = newTableAliasName;
}
// update in belongsTo
for (const bt of meta.belongsTo || []) {
if (bt.rtn !== tableName) continue;
bt._rtn = newTableAliasName;
}
// update in MnyToMany
for (const mm of meta.manyToMany || []) {
if (mm.rtn !== tableName) continue;
mm._rtn = newTableAliasName;
}
for (const v of meta.v || []) {
if (v?.hm?.tn === tableName) v.hm._tn = newTableAliasName;
else if (v?.bt?.rtn === tableName) v.bt._rtn = newTableAliasName;
else if (v?.mm?.rtn === tableName) v.mm._rtn = newTableAliasName;
else if (v?.lk?.ltn === tableName) {
v.lk._ltn = newTableAliasName;
if (v?.lk.type === 'hm') {
v.lk._tn = newTableAliasName;
} else if (v?.lk.type === 'bt' || v.lk.type === 'mm') {
v.lk._rtn = newTableAliasName;
}
} else if (v?.rl?.rltn === tableName) {
v.rl._rltn = newTableAliasName;
if (v.rl?.type === 'hm') {
v.rl._tn = newTableAliasName;
} else if (v.rl.type === 'bt' || v.rl.type === 'mm') {
v.rl._rtn = newTableAliasName;
}
}
// todo: lookup and rollup
// mm._tn = newTableAliasName;
// relatedTableList.add(mm.rtn);
}
// todo: update virtual columns
// todo: delete cache
// todo: update in db
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_models',
{
meta: JSON.stringify(meta)
},
{
title: relTableName
}
);
}
return { meta, relatedTableList, tableName };
// await this.modifyTableNameInACL(oldTableAliasName, newTableAliasName);
}
public async onGqlSchemaUpdate( public async onGqlSchemaUpdate(
_tableName: string, _tableName: string,
_schema: string _schema: string
@ -1556,6 +1729,18 @@ export default abstract class BaseApiBuilder<T extends Noco>
return belongsTo; return belongsTo;
} }
protected generateContextForMeta(meta: any): any {
return this.generateContextForTable(
meta.tn,
meta.columns,
[...meta.hasMany, ...meta.belongsTo],
meta.hasMany,
meta.belongsTo,
'table',
meta._tn
);
}
protected generateContextForTable( protected generateContextForTable(
tn: string, tn: string,
columns: any[], columns: any[],
@ -1609,6 +1794,10 @@ export default abstract class BaseApiBuilder<T extends Noco>
); );
} }
protected getTableName(alias) {
return Object.values(this.metas).find(m => m._tn === alias)?.tn;
}
protected generateContextForHasMany(ctx, tnc: string): any { protected generateContextForHasMany(ctx, tnc: string): any {
this.baseLog(`generateContextForHasMany : '%s' => '%s'`, ctx.tn, tnc); this.baseLog(`generateContextForHasMany : '%s' => '%s'`, ctx.tn, tnc);
return { return {

82
packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts

@ -1656,6 +1656,88 @@ export class GqlApiBuilder extends BaseApiBuilder<Noco> implements XcMetaMgr {
await this.reInitializeGraphqlEndpoint(); await this.reInitializeGraphqlEndpoint();
} }
public async onTableAliasRename(
oldTableAliasName: string,
newTableAliasName: string
): Promise<void> {
this.log(
"onTableAliasRename : '%s' => '%s'",
oldTableAliasName,
newTableAliasName
);
if (oldTableAliasName === newTableAliasName) {
return;
}
const {
// meta,
relatedTableList,
tableName: t
} = await super.onTableAliasRename(oldTableAliasName, newTableAliasName);
for (const table of [t, ...relatedTableList]) {
const meta = this.getMeta(table);
const ctx = this.generateContextForMeta(meta);
ctx.manyToMany = meta.manyToMany;
ctx.v = meta.v;
this.schemas[table] = GqlXcSchemaFactory.create(
this.connectionConfig,
this.generateRendererArgs(ctx)
).getString();
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_models',
{
schema: this.schemas[table]
},
{ title: table }
);
const newResolvers: any[] = Object.keys(
new ExpressXcTsPolicyGql({ ctx }).getObject()
);
const oldResolvers: any[] = Object.keys(
new ExpressXcTsPolicyGql(
this.generateRendererArgs({ ...ctx, _tn: oldTableAliasName })
).getObject()
);
let i = 0;
// this.log(
// `xcTableRename : Updating resolvers name and table name - '%s' => '%s'`,
// oldTablename,
// newTablename
// );
for (const res of newResolvers) {
const oldRes = oldResolvers[i++];
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_resolvers',
{
resolver: res
},
{
title: table,
resolver: oldRes,
handler_type: 1
}
);
}
}
// load routes and models from db
await this.xcTablesRead([...relatedTableList, t]);
await this.reInitializeGraphqlEndpoint();
// }
}
public async onRelationCreate(tnp: string, tnc: string, args): Promise<void> { public async onRelationCreate(tnp: string, tnc: string, args): Promise<void> {
await super.onRelationCreate(tnp, tnc, args); await super.onRelationCreate(tnp, tnc, args);
this.log(`onRelationCreate : Within relation create event handler`); this.log(`onRelationCreate : Within relation create event handler`);

2
packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts

@ -1883,6 +1883,8 @@ export default class NcMetaMgr {
case 'xcVirtualRelationCreate': case 'xcVirtualRelationCreate':
result = await this.xcVirtualRelationCreate(args, req); result = await this.xcVirtualRelationCreate(args, req);
break; break;
case 'ncTableAliasRename':
break;
case 'xcM2MRelationCreate': case 'xcM2MRelationCreate':
result = await this.xcM2MRelationCreate(args, req); result = await this.xcM2MRelationCreate(args, req);

12
packages/nocodb/src/lib/noco/migrations/nc_001_init.ts

@ -1,18 +1,6 @@
// import s3 from "../plugins/s3";
// import gcs from "../plugins/gcs";
// import smtp from "../plugins/smtp";
import cache from '../plugins/cache'; import cache from '../plugins/cache';
import googleAuth from '../plugins/googleAuth'; import googleAuth from '../plugins/googleAuth';
import ses from '../plugins/ses'; import ses from '../plugins/ses';
// import azure from "../plugins/azure";
// import brand from "../plugins/brand";
// import discord from "../plugins/discord";
// import slack from "../plugins/slack";
// import mattermost from "../plugins/mattermost";
// import ee from "../plugins/ee";
// import miniio from "../plugins/miniio";
// import spaces from "../plugins/spaces";
// import githubAuth from "../instant/common/plugins/githubAuth";
const up = async knex => { const up = async knex => {
await knex.schema.createTable('nc_projects', table => { await knex.schema.createTable('nc_projects', table => {

173
packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts

@ -912,6 +912,179 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
// await this.xcTablesPopulate({tableNames: [newTableName]}); // await this.xcTablesPopulate({tableNames: [newTableName]});
} }
public async onTableAliasRename(
oldTableAliasName: string,
newTableAliasName: string
): Promise<void> {
this.log(
"onTableAliasRename : '%s' => '%s'",
oldTableAliasName,
newTableAliasName
);
if (oldTableAliasName === newTableAliasName) {
return;
}
const {
// meta,
relatedTableList,
tableName
} = await super.onTableAliasRename(oldTableAliasName, newTableAliasName);
for (const table of [tableName, ...relatedTableList]) {
const meta = this.getMeta(table);
this.models[table] = this.getBaseModel(meta);
const ctx = this.generateContextForMeta(meta);
const newSwagger = [];
newSwagger.push(new SwaggerXc({ ctx }).getObject());
// update routes
const routes = new ExpressXcTsRoutes({
dir: '',
ctx,
filename: ''
}).getObjectWithoutFunctions();
const routesUpdate = routes.map((route, i) => {
return async () => {
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_routes',
{
path: route.path
},
{
tn: table,
title: table,
type: route.type,
order: i
}
);
};
});
await NcHelp.executeOperations(
routesUpdate,
this.connectionConfig.client
);
/* handle relational routes */
for (const hm of meta.hasMany) {
const rendererArgs = this.generateRendererArgs(
this.generateContextForHasMany(ctx, hm.tn)
);
const hmRoutes = new ExpressXcTsRoutesHm(
rendererArgs
).getObjectWithoutFunctions();
newSwagger.push(new SwaggerXcHm(rendererArgs).getObject());
const routeName = `${table}Hm${hm.tn}`;
// const name = `${ctx.tn}Hm${hm.tn}`;
/* handle has many relational routes */
const hmRoutesInsertion = hmRoutes.map((route, i) => {
return async () => {
// this.log(
// "xcTableAliasRename : Updating table name and route path in 'nc_routes' metatable - '%s' => '%s' (HasMany relation)",
// oldTableAliasName,
// newTableAliasName
// );
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_routes',
{
path: route.path
},
{
title: routeName,
handler: JSON.stringify(route.handler),
tn: table,
type: route.type,
relation_type: 'hasMany',
order: i,
tnc: hm.tn,
handler_type: 1
}
);
};
});
await NcHelp.executeOperations(
hmRoutesInsertion,
this.connectionConfig.client
);
}
/* handle belongs to routes and controllers */
for (const bt of meta.belongsTo) {
const rendererArgs1 = this.generateRendererArgs(
this.generateContextForBelongsTo(
{
...ctx,
tn: bt.tn
},
bt.rtn
)
);
const btRoutes = new ExpressXcTsRoutesBt(
rendererArgs1
).getObjectWithoutFunctions();
newSwagger.push(new SwaggerXcBt(rendererArgs1).getObject());
const routeName = `${table}Bt${bt.rtn}`;
const btRoutesInsertion = btRoutes.map((route, i) => {
return async () => {
// this.log(
// "xcTableRename : Updating table name and route path in 'nc_routes' metatable - '%s' => '%s' (BelongsTo relation)",
// oldTablename,
// newTablename
// );
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_routes',
{
path: route.path
// tn: newTablename,
},
{
tn: table,
title: routeName,
order: i,
type: route.type,
handler: JSON.stringify(route.handler),
relation_type: 'belongsTo',
tnp: bt.rtn,
handler_type: 1
}
);
};
});
await NcHelp.executeOperations(
btRoutesInsertion,
this.connectionConfig.client
);
}
this.mergeAndUpdateSwagger(table, newSwagger);
}
// update metas
// - relations
// - virtual columns
// update swagger docs
// update routes
// load routes and models from db
await this.xcTablesRead([...relatedTableList, tableName]);
await this.onSwaggerDocUpdate(tableName);
}
// NOTE: xc-meta // NOTE: xc-meta
public async xcTableRename( public async xcTableRename(
oldTablename: string, oldTablename: string,

2
packages/nocodb/src/lib/sqlMgr/code/BaseRender.ts

@ -28,7 +28,7 @@ class BaseRender {
* @param {string} - filename - filename of file to be rendered * @param {string} - filename - filename of file to be rendered
* @param {Object} - ctx - context to render this file * @param {Object} - ctx - context to render this file
*/ */
constructor({ dir, filename, ctx }) { constructor({ dir = '', filename = '', ctx }) {
this.dir = dir; this.dir = dir;
this.filename = filename; this.filename = filename;
this.ctx = ctx; this.ctx = ctx;

2
packages/nocodb/src/lib/sqlMgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts

@ -10,7 +10,7 @@ class ExpressXcPolicyGql extends BaseRender {
* @param ctx.columns * @param ctx.columns
* @param ctx.relations * @param ctx.relations
*/ */
constructor({ dir, filename, ctx }) { constructor({ dir = '', filename = '', ctx }) {
super({ dir, filename, ctx }); super({ dir, filename, ctx });
} }

2
packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts

@ -12,7 +12,7 @@ class SwaggerXc extends BaseRender {
* @param ctx.columns * @param ctx.columns
* @param ctx.relations * @param ctx.relations
*/ */
constructor({ dir, filename, ctx }: any) { constructor({ dir = '', filename = '', ctx }: any) {
super({ dir, filename, ctx }); super({ dir, filename, ctx });
} }

Loading…
Cancel
Save