Browse Source

feat: template parser - relation parsing

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/743/head
Pranav C 3 years ago
parent
commit
4ad70af467
  1. 20
      packages/nocodb/src/__tests__/template.ts
  2. 88
      packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts
  3. 35
      packages/nocodb/src/lib/sqlUi/UITypes.ts
  4. 111
      packages/nocodb/src/lib/templateParser/NcTemplateParser.ts

20
packages/nocodb/src/__tests__/template.ts

@ -12,6 +12,16 @@ export default {
cn: 'body', cn: 'body',
uidt: 'LongText' uidt: 'LongText'
} }
],
hasMany: [
{
tn: 'comment'
}
],
manyToMany: [
{
rtn: 'tag'
}
] ]
}, },
{ {
@ -20,11 +30,6 @@ export default {
{ {
cn: 'body', cn: 'body',
uidt: 'LongText' uidt: 'LongText'
},
{
cn: 'blog_id',
uidt: 'ForeignKey',
rtn: 'blog'
} }
] ]
}, },
@ -34,11 +39,6 @@ export default {
{ {
cn: 'title', cn: 'title',
uidt: 'SingleLineText' uidt: 'SingleLineText'
},
{
cn: 'blog_id',
uidt: 'LinkToAnotherRecord',
rtn: 'blog'
} }
] ]
} }

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

@ -4015,11 +4015,13 @@ export default class NcMetaMgr {
d => d?.meta?.dbAlias === dbAlias d => d?.meta?.dbAlias === dbAlias
); );
const { tables } = new NcTemplateParser(connectionConfig?.client).parse( const parser = new NcTemplateParser({
client: connectionConfig?.client,
template template
); });
parser.parse();
for (const table of tables) { for (const table of parser.tables) {
console.log(table); console.log(table);
// create table and trigger listener // create table and trigger listener
@ -4044,23 +4046,81 @@ export default class NcMetaMgr {
} }
}); });
} }
// create table
} }
// iterate over tables // create relations
// iterate over tables
// map column datatypes
// group relations for (const relation of parser.relations) {
// if (args.args.type === 'real') {
const outrel = await this.projectMgr
.getSqlMgr({ id: projectId })
.handleRequest('relationCreate', {
...args,
args: relation
});
if (this.listener) {
await this.listener({
req: {
...args,
args: relation,
api: 'relationCreate'
},
res: outrel,
user: req.user,
ctx: {
req
}
});
}
// } else {
// const outrel = await this.xcVirtualRelationCreate(
// {...args, args: rel1Args},
// req
// );
// if (this.listener) {
// await this.listener({
// req: {
// ...args,
// args: rel1Args,
// api: 'xcVirtualRelationCreate'
// },
// res: outrel,
// user: req.user,
// ctx: {
// req
// }
// });
// }
// create tables // }
}
// create relations //create m2m relations
// for (const m2mRelation of parser.m2mRelations) {
// if (args.args.type === 'real') {
const outrel = await this.xcM2MRelationCreate(
{
...args,
args: m2mRelation
},
req
);
if (this.listener) {
await this.listener({
req: {
...args,
args: m2mRelation,
api: 'xcM2MRelationCreate'
},
res: outrel,
user: req.user,
ctx: {
req
}
});
}
}
} }
protected async xcExportAsCsv(args, _req, res: express.Response) { protected async xcExportAsCsv(args, _req, res: express.Response) {

35
packages/nocodb/src/lib/sqlUi/UITypes.ts

@ -1,6 +1,39 @@
enum UITypes { enum UITypes {
ID = 'ID',
LinkToAnotherRecord = 'LinkToAnotherRecord', LinkToAnotherRecord = 'LinkToAnotherRecord',
ForeignKey = 'ForeignKey' ForeignKey = 'ForeignKey',
Lookup = 'Lookup',
SingleLineText = 'SingleLineText',
LongText = 'LongText',
Attachment = 'Attachment',
Checkbox = 'Checkbox',
MultiSelect = 'MultiSelect',
SingleSelect = 'SingleSelect',
Collaborator = 'Collaborator',
Date = 'Date',
Year = 'Year',
Time = 'Time',
PhoneNumber = 'PhoneNumber',
Email = 'Email',
URL = 'URL',
Number = 'Number',
Decimal = 'Decimal',
Currency = 'Currency',
Percent = 'Percent',
Duration = 'Duration',
Rating = 'Rating',
Formula = 'Formula',
Rollup = 'Rollup',
Count = 'Count',
DateTime = 'DateTime',
CreateTime = 'CreateTime',
LastModifiedTime = 'LastModifiedTime',
AutoNumber = 'AutoNumber',
Geometry = 'Geometry',
JSON = 'JSON',
SpecificDBType = 'SpecificDBType',
Barcode = 'Barcode',
Button = 'Button'
} }
export default UITypes; export default UITypes;

111
packages/nocodb/src/lib/templateParser/NcTemplateParser.ts

@ -18,6 +18,7 @@ export default class NcTemplateParser {
private _tables: any[]; private _tables: any[];
private _relations: any[]; private _relations: any[];
private _m2mRelations: any[];
private template: any; private template: any;
constructor({ client, template }) { constructor({ client, template }) {
@ -28,12 +29,16 @@ export default class NcTemplateParser {
public parse(template?: any): any { public parse(template?: any): any {
const tables = []; const tables = [];
this.template = template || this.template; this.template = template || this.template;
for (const tableTemplate of this.template._tables) { for (const tableTemplate of this.template.tables) {
const table = this.extractTable(tableTemplate); const table = this.extractTable(tableTemplate);
tables.push(table); tables.push(table);
} }
this._tables = tables; this._tables = tables;
for (const tableTemplate of this.template.tables) {
this.extractRelations(tableTemplate);
}
} }
private extractTable(tableTemplate) { private extractTable(tableTemplate) {
@ -65,28 +70,97 @@ export default class NcTemplateParser {
if (!tableColumn?.cn) { if (!tableColumn?.cn) {
throw Error('Missing column name in template'); throw Error('Missing column name in template');
} }
switch (tableColumn.uidt) {
if ( // case UITypes.ForeignKey:
tableColumn.uidt === UITypes.LinkToAnotherRecord || // // todo :
tableColumn.uidt === UITypes.ForeignKey // this.extractRelations(tableColumn, 'bt');
) { // break;
// todo : // case UITypes.LinkToAnotherRecord:
} else { // // todo :
const column = { // this.extractRelations(tableColumn, 'hm');
...this.sqlUi.getNewColumn(''), // // this.extractRelations(tableColumn, 'mm');
cn: tableColumn.cn, // break;
_cn: tableColumn.cn, default:
uidt: tableColumn.uidt, columns.push({
...this.sqlUi.getDataTypeForUiType(tableColumn) ...this.sqlUi.getNewColumn(''),
}; cn: tableColumn.cn,
columns.push(column); _cn: tableColumn.cn,
uidt: tableColumn.uidt,
...this.sqlUi.getDataTypeForUiType(tableColumn)
});
break;
} }
} }
return columns; return columns;
} }
protected extractRelations(_columnTemplate) { protected extractRelations(tableTemplate) {
if (!this._relations) this._relations = []; if (!this._relations) this._relations = [];
if (!this._m2mRelations) this._m2mRelations = [];
for (const hasMany of tableTemplate.hasMany || []) {
const childTable = this.tables.find(table => table.tn === hasMany.tn);
const partentTable = this.tables.find(
table => table.tn === tableTemplate.tn
);
const parentPrimaryColumn = partentTable.columns.find(
column => column.uidt === UITypes.ID
);
// add a column in child table
const childColumnName = `${tableTemplate.tn}_id`;
childTable.columns.push({
cn: childColumnName,
_cn: childColumnName,
rqd: false,
pk: false,
ai: false,
cdf: null,
dt: parentPrimaryColumn.dt,
dtxp: parentPrimaryColumn.dtxp,
dtxs: parentPrimaryColumn.dtxs,
un: parentPrimaryColumn.un,
altered: 1
});
// add relation create entry
this._relations.push({
childColumn: childColumnName,
childTable: hasMany.tn,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
parentColumn: parentPrimaryColumn.cn,
parentTable: tableTemplate.tn,
type: 'real',
updateRelation: false
});
}
for (const manyToMany of tableTemplate.manyToMany || []) {
// @ts-ignore
const childTable = this.tables.find(table => table.tn === manyToMany.rtn);
const parentTable = this.tables.find(
table => table.tn === tableTemplate.tn
);
const parentPrimaryColumn = parentTable.columns.find(
column => column.uidt === UITypes.ID
);
const childPrimaryColumn = childTable.columns.find(
column => column.uidt === UITypes.ID
);
// add many to many relation create entry
this._m2mRelations.push({
alias: 'title8',
childColumn: childPrimaryColumn.cn,
childTable: childTable.tn,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
parentColumn: parentPrimaryColumn.cn,
parentTable: parentTable.tn,
type: 'real',
updateRelation: false
});
}
} }
get tables(): any[] { get tables(): any[] {
@ -96,4 +170,7 @@ export default class NcTemplateParser {
get relations(): any[] { get relations(): any[] {
return this._relations; return this._relations;
} }
get m2mRelations(): any[] {
return this._m2mRelations;
}
} }

Loading…
Cancel
Save