Browse Source

fix: add try-catch block to upgrader

pull/7373/head
mertmit 10 months ago
parent
commit
1494384c29
  1. 422
      packages/nocodb/src/version-upgrader/ncXcdbCreatedAndUpdatedSystemFieldsUpgrader.ts

422
packages/nocodb/src/version-upgrader/ncXcdbCreatedAndUpdatedSystemFieldsUpgrader.ts

@ -15,8 +15,6 @@ import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2';
import getColumnUiType from '~/helpers/getColumnUiType'; import getColumnUiType from '~/helpers/getColumnUiType';
import RequestQueue from '~/utils/RequestQueue'; import RequestQueue from '~/utils/RequestQueue';
// Example Usage:
// An upgrader for upgrading created_at and updated_at columns // An upgrader for upgrading created_at and updated_at columns
// to system column and convert to new uidt CreatedTime and LastModifiedTime // to system column and convert to new uidt CreatedTime and LastModifiedTime
@ -26,6 +24,11 @@ const logger = {
`[ncXcdbCreatedAndUpdatedSystemFieldsUpgrader ${Date.now()}] ` + message, `[ncXcdbCreatedAndUpdatedSystemFieldsUpgrader ${Date.now()}] ` + message,
); );
}, },
error: (message: string) => {
console.error(
`[ncXcdbCreatedAndUpdatedSystemFieldsUpgrader ${Date.now()}] ` + message,
);
},
}; };
/* Enable if planning to remove trigger /* Enable if planning to remove trigger
@ -70,143 +73,202 @@ async function upgradeModels({
await Promise.all( await Promise.all(
models.map(async (model: any) => { models.map(async (model: any) => {
if (model.mm) return; if (model.mm) return;
try {
logger.log(
`Upgrading model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}})`,
);
logger.log( const columns = await model.getColumns(ncMeta);
`Upgrading model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}})`, const oldColumns = columns.map((c) => ({ ...c, cn: c.column_name }));
); let isCreatedTimeExists = false;
let isLastModifiedTimeExists = false;
const columns = await model.getColumns(ncMeta); let isCreatedByExists = false;
const oldColumns = columns.map((c) => ({ ...c, cn: c.column_name })); let isLastModifiedByExists = false;
let isCreatedTimeExists = false; for (const column of columns) {
let isLastModifiedTimeExists = false; if (
let isCreatedByExists = false; ![
let isLastModifiedByExists = false; UITypes.DateTime,
for (const column of columns) { UITypes.CreatedTime,
if ( UITypes.LastModifiedTime,
![ UITypes.CreatedBy,
UITypes.DateTime, UITypes.LastModifiedBy,
UITypes.CreatedTime, ].includes(column.uidt)
UITypes.LastModifiedTime, )
UITypes.CreatedBy, continue;
UITypes.LastModifiedBy,
].includes(column.uidt) if (column.uidt === UITypes.CreatedBy && column.system) {
) isCreatedByExists = true;
continue; continue;
}
if (column.uidt === UITypes.CreatedBy && column.system) {
isCreatedByExists = true; if (column.uidt === UITypes.LastModifiedBy && column.system) {
continue; isLastModifiedByExists = true;
} continue;
}
if (column.uidt === UITypes.LastModifiedBy && column.system) {
isLastModifiedByExists = true; if (
continue; [UITypes.CreatedBy, UITypes.LastModifiedBy].includes(column.uidt)
) {
continue;
}
if (column.uidt === UITypes.CreatedTime && column.system) {
isCreatedTimeExists = true;
continue;
}
if (column.uidt === UITypes.LastModifiedTime && column.system) {
isLastModifiedTimeExists = true;
continue;
}
// if column is created_at or updated_at, update the uidt in meta
if (column.column_name === 'created_at') {
isCreatedTimeExists = true;
await Column.update(
column.id,
{
...column,
uidt: UITypes.CreatedTime,
system: true,
},
ncMeta,
true,
);
/* Enable if planning to remove trigger
if (source.type === 'pg') {
// delete pg trigger if exists
await deletePgTrigger({ column, ncMeta, model });
}
*/
}
if (column.column_name === 'updated_at') {
isLastModifiedTimeExists = true;
await Column.update(
column.id,
{
...column,
uidt: UITypes.LastModifiedTime,
system: true,
cdf: '',
au: false,
},
ncMeta,
true,
);
}
} }
if ([UITypes.CreatedBy, UITypes.LastModifiedBy].includes(column.uidt)) { // get existing columns from database
continue; const sqlClient = await NcConnectionMgrv2.getSqlClient(
} source,
ncMeta.knex,
);
if (column.uidt === UITypes.CreatedTime && column.system) { const dbColumns =
isCreatedTimeExists = true; (
continue; await sqlClient.columnList({
} tn: model.table_name,
schema: source.getConfig()?.schema,
})
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn })) || [];
if (column.uidt === UITypes.LastModifiedTime && column.system) { // if no columns found skip since table might not be there
isLastModifiedTimeExists = true; if (!dbColumns.length) {
continue; logger.log(
`Skipping upgrade of model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}}) since columns not found`,
);
return;
} }
// if column is created_at or updated_at, update the uidt in meta // create created_at & updated_at and created_by & updated_by columns
if (column.column_name === 'created_at') { const newColumns = [];
isCreatedTimeExists = true; const existingDbColumns = [];
await Column.update(
column.id, if (!isCreatedTimeExists) {
{ // check column exist and add to meta if found
...column, const columnName = getUniqueColumnName(columns, 'created_at');
const dbColumn = dbColumns.find((c) => c.cn === columnName);
// if column already exist, just update the meta
if (
dbColumn &&
getColumnUiType(source, dbColumn) === UITypes.DateTime
) {
existingDbColumns.push({
...dbColumn,
uidt: UITypes.CreatedTime, uidt: UITypes.CreatedTime,
column_name: columnName,
title: getUniqueColumnAliasName(columns, 'CreatedAt'),
system: true, system: true,
}, });
ncMeta, } else {
true, newColumns.push({
); ...(await getColumnPropsFromUIDT(
{
/* Enable if planning to remove trigger uidt: UITypes.CreatedTime,
if (source.type === 'pg') { column_name: getUniqueColumnName(
// delete pg trigger if exists [...columns, ...dbColumns],
await deletePgTrigger({ column, ncMeta, model }); 'created_at',
}*/ ),
} title: getUniqueColumnAliasName(columns, 'CreatedAt'),
if (column.column_name === 'updated_at') { },
isLastModifiedTimeExists = true; source,
await Column.update( )),
column.id, cdf: null,
{
...column,
uidt: UITypes.LastModifiedTime,
system: true, system: true,
cdf: '', altered: Altered.NEW_COLUMN,
au: false, });
}, }
ncMeta,
true,
);
} }
}
// get existing columns from database if (!isLastModifiedTimeExists) {
const sqlClient = await NcConnectionMgrv2.getSqlClient( const columnName = getUniqueColumnName(columns, 'created_at');
source, const dbColumn = dbColumns.find((c) => c.cn === columnName);
ncMeta.knex,
);
const dbColumns =
(
await sqlClient.columnList({
tn: model.table_name,
schema: source.getConfig()?.schema,
})
)?.data?.list?.map((c) => ({ ...c, column_name: c.cn })) || [];
// if no columns found skip since table might not be there // if column already exist, just update the meta
if (!dbColumns.length) { if (
logger.log( dbColumn &&
`Skipping upgrade of model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}}) since columns not found`, getColumnUiType(source, dbColumn) === UITypes.DateTime
); ) {
return; existingDbColumns.push({
} uidt: UITypes.LastModifiedTime,
...dbColumn,
column_name: columnName,
title: getUniqueColumnAliasName(columns, 'UpdatedAt'),
system: true,
});
} else {
newColumns.push({
...(await getColumnPropsFromUIDT(
{
uidt: UITypes.LastModifiedTime,
column_name: getUniqueColumnName(
[...columns, ...dbColumns],
'updated_at',
),
title: getUniqueColumnAliasName(columns, 'UpdatedAt'),
},
source,
)),
cdf: null,
system: true,
altered: Altered.NEW_COLUMN,
});
}
}
// create created_at & updated_at and created_by & updated_by columns if (!isCreatedByExists) {
const newColumns = [];
const existingDbColumns = [];
if (!isCreatedTimeExists) {
// check column exist and add to meta if found
const columnName = getUniqueColumnName(columns, 'created_at');
const dbColumn = dbColumns.find((c) => c.cn === columnName);
// if column already exist, just update the meta
if (
dbColumn &&
getColumnUiType(source, dbColumn) === UITypes.DateTime
) {
existingDbColumns.push({
...dbColumn,
uidt: UITypes.CreatedTime,
column_name: columnName,
title: getUniqueColumnAliasName(columns, 'CreatedAt'),
system: true,
});
} else {
newColumns.push({ newColumns.push({
...(await getColumnPropsFromUIDT( ...(await getColumnPropsFromUIDT(
{ {
uidt: UITypes.CreatedTime, uidt: UITypes.CreatedBy,
column_name: getUniqueColumnName( column_name: getUniqueColumnName(
[...columns, ...dbColumns], [...columns, ...dbColumns],
'created_at', 'created_by',
), ),
title: getUniqueColumnAliasName(columns, 'CreatedAt'), title: getUniqueColumnAliasName(columns, 'nc_created_by'),
}, },
source, source,
)), )),
@ -215,34 +277,17 @@ async function upgradeModels({
altered: Altered.NEW_COLUMN, altered: Altered.NEW_COLUMN,
}); });
} }
}
if (!isLastModifiedTimeExists) { if (!isLastModifiedByExists) {
const columnName = getUniqueColumnName(columns, 'created_at');
const dbColumn = dbColumns.find((c) => c.cn === columnName);
// if column already exist, just update the meta
if (
dbColumn &&
getColumnUiType(source, dbColumn) === UITypes.DateTime
) {
existingDbColumns.push({
uidt: UITypes.LastModifiedTime,
...dbColumn,
column_name: columnName,
title: getUniqueColumnAliasName(columns, 'UpdatedAt'),
system: true,
});
} else {
newColumns.push({ newColumns.push({
...(await getColumnPropsFromUIDT( ...(await getColumnPropsFromUIDT(
{ {
uidt: UITypes.LastModifiedTime, uidt: UITypes.LastModifiedBy,
column_name: getUniqueColumnName( column_name: getUniqueColumnName(
[...columns, ...dbColumns], [...columns, ...dbColumns],
'updated_at', 'updated_by',
), ),
title: getUniqueColumnAliasName(columns, 'UpdatedAt'), title: getUniqueColumnAliasName(columns, 'nc_updated_by'),
}, },
source, source,
)), )),
@ -251,78 +296,45 @@ async function upgradeModels({
altered: Altered.NEW_COLUMN, altered: Altered.NEW_COLUMN,
}); });
} }
}
if (!isCreatedByExists) {
newColumns.push({
...(await getColumnPropsFromUIDT(
{
uidt: UITypes.CreatedBy,
column_name: getUniqueColumnName(
[...columns, ...dbColumns],
'created_by',
),
title: getUniqueColumnAliasName(columns, 'nc_created_by'),
},
source,
)),
cdf: null,
system: true,
altered: Altered.NEW_COLUMN,
});
}
if (!isLastModifiedByExists) { // alter table and add new columns if any
newColumns.push({ if (newColumns.length) {
...(await getColumnPropsFromUIDT( logger.log(
`Altering table '${model.title}'(${model.id}) from base '${base.title}'(${base.id}}) for new columns`,
);
// update column in db
const tableUpdateBody = {
...model,
tn: model.table_name,
originalColumns: oldColumns,
columns: [...columns, ...newColumns].map((c) => ({
...c,
cn: c.column_name,
})),
};
const sqlMgr = ProjectMgrv2.getSqlMgr({ id: source.base_id }, ncMeta);
await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody);
}
for (const newColumn of [...existingDbColumns, ...newColumns]) {
await Column.insert(
{ {
uidt: UITypes.LastModifiedBy, ...newColumn,
column_name: getUniqueColumnName( system: 1,
[...columns, ...dbColumns], fk_model_id: model.id,
'updated_by',
),
title: getUniqueColumnAliasName(columns, 'nc_updated_by'),
}, },
source, ncMeta,
)), );
cdf: null, }
system: true,
altered: Altered.NEW_COLUMN,
});
}
// alter table and add new columns if any
if (newColumns.length) {
logger.log( logger.log(
`Altering table '${model.title}'(${model.id}) from base '${base.title}'(${base.id}}) for new columns`, `Upgraded model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}})`,
); );
// update column in db } catch (e) {
const tableUpdateBody = { logger.error(
...model, `Upgrading model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}}) failed`,
tn: model.table_name,
originalColumns: oldColumns,
columns: [...columns, ...newColumns].map((c) => ({
...c,
cn: c.column_name,
})),
};
const sqlMgr = ProjectMgrv2.getSqlMgr({ id: source.base_id }, ncMeta);
await sqlMgr.sqlOpPlus(source, 'tableUpdate', tableUpdateBody);
}
for (const newColumn of [...existingDbColumns, ...newColumns]) {
await Column.insert(
{
...newColumn,
system: 1,
fk_model_id: model.id,
},
ncMeta,
); );
throw e;
} }
logger.log(
`Upgraded model '${model.title}'(${model.id}) from base '${base.title}'(${base.id}})`,
);
}), }),
); );
} }
@ -373,7 +385,7 @@ export default async function ({ ncMeta }: NcUpgraderCtx) {
})`, })`,
); );
return upgradeModels({ ncMeta, source, base }).then(() => { await upgradeModels({ ncMeta, source, base }).then(() => {
logger.log( logger.log(
`Upgraded base '${base.title}'(${base.id},${source.id}) (${i + 1}/${ `Upgraded base '${base.title}'(${base.id},${source.id}) (${i + 1}/${
sources.length sources.length

Loading…
Cancel
Save