|
|
@ -1,3 +1,4 @@ |
|
|
|
|
|
|
|
import { Knex } from 'knex'; |
|
|
|
import { NcUpgraderCtx } from './NcUpgrader'; |
|
|
|
import { NcUpgraderCtx } from './NcUpgrader'; |
|
|
|
import { MetaTable } from '../utils/globals'; |
|
|
|
import { MetaTable } from '../utils/globals'; |
|
|
|
import Base from '../models/Base'; |
|
|
|
import Base from '../models/Base'; |
|
|
@ -29,7 +30,7 @@ function getTnPath(knex: XKnex, tb: Model) { |
|
|
|
const schema = (knex as any).searchPath?.(); |
|
|
|
const schema = (knex as any).searchPath?.(); |
|
|
|
const clientType = knex.clientType(); |
|
|
|
const clientType = knex.clientType(); |
|
|
|
if (clientType === 'mssql' && schema) { |
|
|
|
if (clientType === 'mssql' && schema) { |
|
|
|
return knex.raw('??.??', [schema, tb.table_name]); |
|
|
|
return knex.raw('??.??', [schema, tb.table_name]).toQuery(); |
|
|
|
} else if (clientType === 'snowflake') { |
|
|
|
} else if (clientType === 'snowflake') { |
|
|
|
return [ |
|
|
|
return [ |
|
|
|
knex.client.config.connection.database, |
|
|
|
knex.client.config.connection.database, |
|
|
@ -45,26 +46,71 @@ export default async function ({ ncMeta }: NcUpgraderCtx) { |
|
|
|
const bases: BaseType[] = await ncMeta.metaList2(null, null, MetaTable.BASES); |
|
|
|
const bases: BaseType[] = await ncMeta.metaList2(null, null, MetaTable.BASES); |
|
|
|
for (const _base of bases) { |
|
|
|
for (const _base of bases) { |
|
|
|
const base = new Base(_base); |
|
|
|
const base = new Base(_base); |
|
|
|
const knex: XKnex = base.is_meta |
|
|
|
|
|
|
|
|
|
|
|
// skip if the prodect_id is missing
|
|
|
|
|
|
|
|
if (!base.project_id) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const project = await ncMeta.metaGet2(null, null, MetaTable.PROJECT, { |
|
|
|
|
|
|
|
id: base.project_id, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// skip if the project is missing
|
|
|
|
|
|
|
|
if (!project) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isProjectDeleted = project.deleted; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const knex: Knex = base.is_meta |
|
|
|
? ncMeta.knexConnection |
|
|
|
? ncMeta.knexConnection |
|
|
|
: NcConnectionMgrv2.get(base); |
|
|
|
: NcConnectionMgrv2.get(base); |
|
|
|
const models = await base.getModels(ncMeta); |
|
|
|
const models = await base.getModels(ncMeta); |
|
|
|
|
|
|
|
|
|
|
|
for (const model of models) { |
|
|
|
for (const model of models) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// if the table is missing in database, skip
|
|
|
|
|
|
|
|
if (!(await knex.schema.hasTable(getTnPath(knex, model)))) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const updateRecords = []; |
|
|
|
const updateRecords = []; |
|
|
|
const columns = await ( |
|
|
|
|
|
|
|
await Model.get(model.id, ncMeta) |
|
|
|
// get all attachment & primary key columns
|
|
|
|
).getColumns(ncMeta); |
|
|
|
// and filter out the columns that are missing in database
|
|
|
|
|
|
|
|
const columns = await (await Model.get(model.id, ncMeta)) |
|
|
|
|
|
|
|
.getColumns(ncMeta) |
|
|
|
|
|
|
|
.then(async (columns) => { |
|
|
|
|
|
|
|
const filteredColumns = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const column of columns) { |
|
|
|
|
|
|
|
if (column.uidt !== UITypes.Attachment && !column.pk) continue; |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
!(await knex.schema.hasColumn( |
|
|
|
|
|
|
|
getTnPath(knex, model), |
|
|
|
|
|
|
|
column.column_name |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
filteredColumns.push(column); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return filteredColumns; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const attachmentColumns = columns |
|
|
|
const attachmentColumns = columns |
|
|
|
.filter((c) => c.uidt === UITypes.Attachment) |
|
|
|
.filter((c) => c.uidt === UITypes.Attachment) |
|
|
|
.map((c) => c.column_name); |
|
|
|
.map((c) => c.column_name); |
|
|
|
if (attachmentColumns.length === 0) { |
|
|
|
if (attachmentColumns.length === 0) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
const primaryKeys = columns.filter((c) => c.pk).map((c) => c.column_name); |
|
|
|
const primaryKeys = columns |
|
|
|
const records = await knex(getTnPath(knex, model)).select([ |
|
|
|
.filter((c) => c.pk) |
|
|
|
...primaryKeys, |
|
|
|
.map((c) => c.column_name); |
|
|
|
...attachmentColumns, |
|
|
|
|
|
|
|
]); |
|
|
|
const records = await knex(getTnPath(knex, model)).select(); |
|
|
|
|
|
|
|
|
|
|
|
for (const record of records) { |
|
|
|
for (const record of records) { |
|
|
|
for (const attachmentColumn of attachmentColumns) { |
|
|
|
for (const attachmentColumn of attachmentColumns) { |
|
|
|
let attachmentMeta: Array<{ |
|
|
|
let attachmentMeta: Array<{ |
|
|
@ -121,6 +167,12 @@ export default async function ({ ncMeta }: NcUpgraderCtx) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
await Promise.all(updateRecords); |
|
|
|
await Promise.all(updateRecords); |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
// ignore the error related to deleted project
|
|
|
|
|
|
|
|
if (!isProjectDeleted) { |
|
|
|
|
|
|
|
throw e; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|