Browse Source

feat: meta-diff apis for single base

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/3573/head
mertmit 2 years ago
parent
commit
4b09930e9d
  1. 206
      packages/nocodb/src/lib/meta/api/metaDiffApis.ts
  2. 55
      scripts/sdk/swagger.json

206
packages/nocodb/src/lib/meta/api/metaDiffApis.ts

@ -542,6 +542,17 @@ export async function metaDiff(req, res) {
res.json(changes); res.json(changes);
} }
export async function baseMetaDiff(req, res) {
const project = await Project.getWithInfo(req.params.projectId);
const base = await Base.get(req.params.baseId);
let changes = []
const sqlClient = NcConnectionMgrv2.getSqlClient(base);
changes = changes.concat(await getMetaDiff(sqlClient, project, base));
res.json(changes);
}
export async function metaDiffSync(req, res) { export async function metaDiffSync(req, res) {
const project = await Project.getWithInfo(req.params.projectId); const project = await Project.getWithInfo(req.params.projectId);
for (const base of project.bases) { for (const base of project.bases) {
@ -736,6 +747,191 @@ export async function metaDiffSync(req, res) {
res.json({ msg: 'success' }); res.json({ msg: 'success' });
} }
export async function baseMetaDiffSync(req, res) {
const project = await Project.getWithInfo(req.params.projectId);
const base = await Base.get(req.params.baseId);
const virtualColumnInsert: Array<() => Promise<void>> = [];
// @ts-ignore
const sqlClient = NcConnectionMgrv2.getSqlClient(base);
const changes = await getMetaDiff(sqlClient, project, base);
/* Get all relations */
// const relations = (await sqlClient.relationListAll())?.data?.list;
for (const { table_name, detectedChanges } of changes) {
for (const change of detectedChanges) {
switch (change.type) {
case MetaDiffType.TABLE_NEW:
{
const columns = (
await sqlClient.columnList({ tn: table_name })
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn }));
mapDefaultPrimaryValue(columns);
const model = await Model.insert(project.id, base.id, {
table_name: table_name,
title: getTableNameAlias(table_name, base.is_meta ? project.prefix : '', base),
type: ModelTypes.TABLE,
});
for (const column of columns) {
await Column.insert({
uidt: getColumnUiType(base, column),
fk_model_id: model.id,
...column,
title: getColumnNameAlias(column.column_name, base),
});
}
}
break;
case MetaDiffType.VIEW_NEW:
{
const columns = (
await sqlClient.columnList({ tn: table_name })
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn }));
mapDefaultPrimaryValue(columns);
const model = await Model.insert(project.id, base.id, {
table_name: table_name,
title: getTableNameAlias(table_name, project.prefix, base),
type: ModelTypes.VIEW,
});
for (const column of columns) {
await Column.insert({
uidt: getColumnUiType(base, column),
fk_model_id: model.id,
...column,
title: getColumnNameAlias(column.column_name, base),
});
}
}
break;
case MetaDiffType.TABLE_REMOVE:
case MetaDiffType.VIEW_REMOVE:
{
await change.model.delete();
}
break;
case MetaDiffType.TABLE_COLUMN_ADD:
case MetaDiffType.VIEW_COLUMN_ADD:
{
const columns = (
await sqlClient.columnList({ tn: table_name })
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn }));
const column = columns.find((c) => c.cn === change.cn);
column.uidt = getColumnUiType(base, column);
//todo: inflection
column.title = getColumnNameAlias(column.cn, base);
await Column.insert({ fk_model_id: change.id, ...column });
}
// update old
// populateParams.tableNames.push({ tn });
// populateParams.oldMetas[tn] = oldMetas.find(m => m.tn === tn);
break;
case MetaDiffType.TABLE_COLUMN_TYPE_CHANGE:
case MetaDiffType.VIEW_COLUMN_TYPE_CHANGE:
{
const columns = (
await sqlClient.columnList({ tn: table_name })
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn }));
const column = columns.find((c) => c.cn === change.cn);
const metaFact = ModelXcMetaFactory.create(
{ client: base.type },
{}
);
column.uidt = metaFact.getUIDataType(column);
column.title = change.column.title;
await Column.update(change.column.id, column);
}
break;
case MetaDiffType.TABLE_COLUMN_REMOVE:
case MetaDiffType.VIEW_COLUMN_REMOVE:
await change.column.delete();
break;
case MetaDiffType.TABLE_RELATION_REMOVE:
case MetaDiffType.TABLE_VIRTUAL_M2M_REMOVE:
await change.column.delete();
break;
case MetaDiffType.TABLE_RELATION_ADD:
{
virtualColumnInsert.push(async () => {
const parentModel = await Model.getByIdOrName({
project_id: base.project_id,
base_id: base.id,
table_name: change.rtn,
});
const childModel = await Model.getByIdOrName({
project_id: base.project_id,
base_id: base.id,
table_name: change.tn,
});
const parentCol = await parentModel
.getColumns()
.then((cols) => cols.find((c) => c.column_name === change.rcn));
const childCol = await childModel
.getColumns()
.then((cols) => cols.find((c) => c.column_name === change.cn));
await Column.update(childCol.id, {
...childCol,
uidt: UITypes.ForeignKey,
system: true,
});
if (change.relationType === RelationTypes.BELONGS_TO) {
const title = getUniqueColumnAliasName(
childModel.columns,
`${parentModel.title || parentModel.table_name}`
);
await Column.insert<LinkToAnotherRecordColumn>({
uidt: UITypes.LinkToAnotherRecord,
title,
fk_model_id: childModel.id,
fk_related_model_id: parentModel.id,
type: RelationTypes.BELONGS_TO,
fk_parent_column_id: parentCol.id,
fk_child_column_id: childCol.id,
virtual: false,
});
} else if (change.relationType === RelationTypes.HAS_MANY) {
const title = getUniqueColumnAliasName(
childModel.columns,
`${childModel.title || childModel.table_name} List`
);
await Column.insert<LinkToAnotherRecordColumn>({
uidt: UITypes.LinkToAnotherRecord,
title,
fk_model_id: parentModel.id,
fk_related_model_id: childModel.id,
type: RelationTypes.HAS_MANY,
fk_parent_column_id: parentCol.id,
fk_child_column_id: childCol.id,
virtual: false,
});
}
});
}
break;
}
}
}
await NcHelp.executeOperations(virtualColumnInsert, base.type);
// populate m2m relations
await extractAndGenerateManyToManyRelations(await base.getModels());
Tele.emit('evt', { evt_type: 'baseMetaDiff:synced' });
res.json({ msg: 'success' });
}
async function isMMRelationExist( async function isMMRelationExist(
model: Model, model: Model,
assocModel: Model, assocModel: Model,
@ -877,4 +1073,14 @@ router.post(
metaApiMetrics, metaApiMetrics,
ncMetaAclMw(metaDiffSync, 'metaDiffSync') ncMetaAclMw(metaDiffSync, 'metaDiffSync')
); );
router.get(
'/api/v1/db/meta/projects/:projectId/meta-diff/:baseId',
metaApiMetrics,
ncMetaAclMw(baseMetaDiff, 'baseMetaDiff')
);
router.post(
'/api/v1/db/meta/projects/:projectId/meta-diff/:baseId',
metaApiMetrics,
ncMetaAclMw(baseMetaDiffSync, 'baseMetaDiffSync')
);
export default router; export default router;

55
scripts/sdk/swagger.json

@ -3266,6 +3266,61 @@
} }
} }
}, },
"/api/v1/db/meta/projects/{projectId}/meta-diff/{baseId}": {
"parameters": [
{
"schema": {
"type": "string"
},
"name": "projectId",
"in": "path",
"required": true
},
{
"schema": {
"type": "string"
},
"name": "baseId",
"in": "path",
"required": true
}
],
"post": {
"summary": "",
"operationId": "base-meta-diff-sync",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"tags": [
"Base"
]
},
"get": {
"summary": "",
"operationId": "base-meta-diff-get",
"parameters": [],
"tags": [
"Base"
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {}
}
}
}
}
}
},
"/api/v1/db/data/{orgs}/{projectName}/{tableName}": { "/api/v1/db/data/{orgs}/{projectName}/{tableName}": {
"parameters": [ "parameters": [
{ {

Loading…
Cancel
Save