Skip to content

Commit

Permalink
revert: change field name and type is impossible for current convert …
Browse files Browse the repository at this point in the history
…logic
  • Loading branch information
tea-artist committed Dec 6, 2023
1 parent 419793f commit 5427464
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 20 deletions.
3 changes: 3 additions & 0 deletions apps/nestjs-backend/src/db-provider/db.provider.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export interface IDbProvider {

dropColumn(tableName: string, columnName: string): string[];

// sql response format: { name: string }[], name for columnName.
columnInfo(tableName: string, columnName: string): string;

modifyColumnSchema(tableName: string, columnName: string, schemaType: SchemaType): string[];

batchInsertSql(tableName: string, insertData: ReadonlyArray<unknown>): string;
Expand Down
29 changes: 23 additions & 6 deletions apps/nestjs-backend/src/db-provider/postgres.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,30 @@ export class PostgresProvider implements IDbProvider {
.map((item) => item.sql);
}

modifyColumnSchema(tableName: string, columnName: string, schemaType: SchemaType): string[] {
return this.knex.schema
.alterTable(tableName, (table) => {
table[schemaType](columnName).alter();
columnInfo(tableName: string, columnName: string): string {
const [schemaName, dbTableName] = tableName.split('.');
return this.knex
.select({
name: 'column_name',
})
.toSQL()
.map((item) => item.sql);
.from('information_schema.columns')
.where({
table_schema: schemaName,
table_name: dbTableName,
column_name: columnName,
})
.toQuery();
}

modifyColumnSchema(tableName: string, columnName: string, schemaType: SchemaType): string[] {
return [this.knex(tableName).update(columnName, null).toQuery()].concat(
this.knex.schema
.alterTable(tableName, (table) => {
table[schemaType](columnName).alter();
})
.toSQL()
.map((item) => item.sql)
);
}

batchInsertSql(tableName: string, insertData: ReadonlyArray<unknown>): string {
Expand Down
4 changes: 4 additions & 0 deletions apps/nestjs-backend/src/db-provider/sqlite.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export class SqliteProvider implements IDbProvider {
return [this.knex.raw('ALTER TABLE ?? DROP COLUMN ??', [tableName, columnName]).toQuery()];
}

columnInfo(tableName: string, _columnName: string): string {
return this.knex.raw(`PRAGMA table_info(??)`, [tableName]).toQuery();
}

batchInsertSql(tableName: string, insertData: ReadonlyArray<unknown>): string {
// TODO: The code doesn't taste good because knex utilizes the "select-stmt" mode to construct SQL queries for SQLite batchInsert.
// This is a temporary solution, and I'm actively keeping an eye on this issue for further developments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export class FieldConvertingService {
return ops.filter(Boolean) as IOtOperation[];
}

private async updateDbFieldType(field: IFieldInstance) {
private async updateDbFieldType(dbTableName: string, field: IFieldInstance) {
const ops: IOtOperation[] = [];
const dbFieldType = this.fieldSupplementService.getDbFieldType(
field.type,
Expand All @@ -230,15 +230,19 @@ export class FieldConvertingService {

if (field.dbFieldType !== dbFieldType) {
const op1 = this.buildOpAndMutateField(field, 'dbFieldType', dbFieldType);
const op2 = this.buildOpAndMutateField(field, 'dbFieldName', field.dbFieldName + '_');
op1 && ops.push(op1);
op2 && ops.push(op2);
await this.fieldService.alterTableAddField(dbTableName, [field]);
}
return ops;
}

private async generateReferenceFieldOps(fieldId: string) {
const topoOrdersContext = await this.fieldCalculationService.getTopoOrdersContext([fieldId]);

const { fieldMap, topoOrdersByFieldId, fieldId2TableId } = topoOrdersContext;
const { fieldMap, topoOrdersByFieldId, fieldId2TableId, tableId2DbTableName } =
topoOrdersContext;
const topoOrders = topoOrdersByFieldId[fieldId];
if (topoOrders.length <= 1) {
return {};
Expand All @@ -251,14 +255,15 @@ export class FieldConvertingService {
// curField will be mutate in loop
const curField = fieldMap[topoOrder.id];
const tableId = fieldId2TableId[curField.id];
const dbTableName = tableId2DbTableName[tableId];
if (curField.isLookup) {
pushOpsMap(tableId, curField.id, this.updateLookupField(curField, fieldMap));
} else if (curField.type === FieldType.Formula) {
pushOpsMap(tableId, curField.id, this.updateFormulaField(curField, fieldMap));
} else if (curField.type === FieldType.Rollup) {
pushOpsMap(tableId, curField.id, this.updateRollupField(curField, fieldMap));
}
const ops = await this.updateDbFieldType(curField);
const ops = await this.updateDbFieldType(dbTableName, curField);
pushOpsMap(tableId, curField.id, ops);
}

Expand Down Expand Up @@ -989,6 +994,18 @@ export class FieldConvertingService {
}
}

// we should create a new field in visual db, because we can not modify a field in sqlite.
// so we should generate a new dbFieldName for the modified field.
private async updateDbFieldName(tableId: string, newField: IFieldVo, oldField: IFieldVo) {
if (newField.dbFieldType === oldField.dbFieldType) {
return;
}
newField.dbFieldName = newField.dbFieldName + '_';
const dbTableName = await this.fieldService.getDbTableName(tableId);

await this.fieldService.alterTableAddField(dbTableName, [newField]);
}

async updateFieldById(tableId: string, fieldId: string, updateFieldRo: IUpdateFieldRo) {
const fieldVo = await this.fieldService.getField(tableId, fieldId);
if (!fieldVo) {
Expand All @@ -1002,6 +1019,8 @@ export class FieldConvertingService {
oldFieldInstance
);

await this.updateDbFieldName(tableId, newFieldVo, fieldVo);

const newFieldInstance = createFieldInstanceByVo(newFieldVo);

await this.updateField(tableId, newFieldInstance, oldFieldInstance);
Expand Down
21 changes: 10 additions & 11 deletions apps/nestjs-backend/src/features/field/field.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ export class FieldService implements IAdapterService {

async generateDbFieldName(tableId: string, name: string): Promise<string> {
let dbFieldName = convertNameToValidCharacter(name, 40);
const field = await this.prismaService.txClient().field.findFirst({
where: { tableId, dbFieldName, deletedTime: null },
});

const query = this.dbProvider.columnInfo(await this.getDbTableName(tableId), dbFieldName);
const columns = await this.prismaService.txClient().$queryRawUnsafe<{ name: string }[]>(query);
// fallback logic
if (field) {
if (columns.some((column) => column.name === dbFieldName)) {
dbFieldName += new Date().getTime();
}
return dbFieldName;
Expand Down Expand Up @@ -433,7 +432,7 @@ export class FieldService implements IAdapterService {
await this.deleteMany(tableId, [{ docId: fieldId, version }]);
}

private async handleFieldProperty(fieldId: string, opContext: IOpContext) {
private async handleFieldProperty(_fieldId: string, opContext: IOpContext) {
const { key, newValue } = opContext as ISetFieldPropertyOpContext;
if (key === 'options') {
if (!newValue) {
Expand All @@ -454,13 +453,13 @@ export class FieldService implements IAdapterService {
return { [key]: JSON.stringify(newValue) ?? null };
}

if (key === 'dbFieldType') {
await this.alterTableModifyFieldType(fieldId, newValue as DbFieldType);
}
// if (key === 'dbFieldType') {
// await this.alterTableModifyFieldType(fieldId, newValue as DbFieldType);
// }

if (key === 'dbFieldName') {
await this.alterTableModifyFieldName(fieldId, newValue as string);
}
// if (key === 'dbFieldName') {
// await this.alterTableModifyFieldName(fieldId, newValue as string);
// }

return { [key]: newValue ?? null };
}
Expand Down

0 comments on commit 5427464

Please sign in to comment.