chore: remove field from db (#3233)
* chore: remove field from db * fix: test * chore: test
This commit is contained in:
parent
a8ae078baa
commit
2289bb7418
@ -97,7 +97,7 @@ describe('collection', () => {
|
||||
const field = collection.getField('name');
|
||||
const r1 = await field.existsInDb();
|
||||
expect(r1).toBe(true);
|
||||
await field.removeFromDb();
|
||||
await collection.removeFieldFromDb('name');
|
||||
const r2 = await field.existsInDb();
|
||||
expect(r2).toBe(false);
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
ModelOptions,
|
||||
ModelStatic,
|
||||
QueryInterfaceDropTableOptions,
|
||||
QueryInterfaceOptions,
|
||||
SyncOptions,
|
||||
Transactionable,
|
||||
Utils,
|
||||
@ -382,6 +383,84 @@ export class Collection<
|
||||
return this.context.database.removeCollection(this.name);
|
||||
}
|
||||
|
||||
async removeFieldFromDb(name: string, options?: QueryInterfaceOptions) {
|
||||
const field = this.getField(name);
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attribute = this.model.rawAttributes[name];
|
||||
|
||||
if (!attribute) {
|
||||
field.remove();
|
||||
// console.log('field is not attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (this.isInherited() && this.parentFields().has(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((this.model as any)._virtualAttributes.has(this.name)) {
|
||||
field.remove();
|
||||
// console.log('field is virtual attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.model.primaryKeyAttributes.includes(this.name)) {
|
||||
// 主键不能删除
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.model.options.timestamps !== false) {
|
||||
// timestamps 相关字段不删除
|
||||
let timestampsFields = ['createdAt', 'updatedAt', 'deletedAt'];
|
||||
if (this.db.options.underscored) {
|
||||
timestampsFields = timestampsFields.map((fieldName) => snakeCase(fieldName));
|
||||
}
|
||||
if (timestampsFields.includes(field.columnName())) {
|
||||
this.fields.delete(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 排序字段通过 sortable 控制
|
||||
const sortable = this.options.sortable;
|
||||
if (sortable) {
|
||||
let sortField: any;
|
||||
if (sortable === true) {
|
||||
sortField = 'sort';
|
||||
} else if (typeof sortable === 'string') {
|
||||
sortField = sortable;
|
||||
} else if (sortable.name) {
|
||||
sortField = sortable.name || 'sort';
|
||||
}
|
||||
if (field.name === sortField) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isView()) {
|
||||
field.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
const columnReferencesCount = _.filter(this.model.rawAttributes, (attr) => attr.field == field.columnName()).length;
|
||||
|
||||
if (
|
||||
(await field.existsInDb({
|
||||
transaction: options?.transaction,
|
||||
})) &&
|
||||
columnReferencesCount == 1
|
||||
) {
|
||||
const queryInterface = this.db.sequelize.getQueryInterface();
|
||||
await queryInterface.removeColumn(this.getTableNameWithSchema(), field.columnName(), options);
|
||||
}
|
||||
|
||||
field.remove();
|
||||
}
|
||||
|
||||
async removeFromDb(options?: QueryInterfaceDropTableOptions) {
|
||||
if (
|
||||
!this.isView() &&
|
||||
|
@ -1,15 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
DataType,
|
||||
ModelAttributeColumnOptions,
|
||||
ModelIndexesOptions,
|
||||
QueryInterfaceOptions,
|
||||
SyncOptions,
|
||||
Transactionable,
|
||||
} from 'sequelize';
|
||||
import { DataType, ModelAttributeColumnOptions, ModelIndexesOptions, SyncOptions, Transactionable } from 'sequelize';
|
||||
import { Collection } from '../collection';
|
||||
import { Database } from '../database';
|
||||
import { InheritedCollection } from '../inherited-collection';
|
||||
import { ModelEventTypes } from '../types';
|
||||
import { snakeCase } from '../utils';
|
||||
|
||||
@ -102,84 +94,6 @@ export abstract class Field {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
async removeFromDb(options?: QueryInterfaceOptions) {
|
||||
const attribute = this.collection.model.rawAttributes[this.name];
|
||||
|
||||
if (!attribute) {
|
||||
this.remove();
|
||||
// console.log('field is not attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.collection.isInherited() && (<InheritedCollection>this.collection).parentFields().has(this.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((this.collection.model as any)._virtualAttributes.has(this.name)) {
|
||||
this.remove();
|
||||
// console.log('field is virtual attribute');
|
||||
return;
|
||||
}
|
||||
if (this.collection.model.primaryKeyAttributes.includes(this.name)) {
|
||||
// 主键不能删除
|
||||
return;
|
||||
}
|
||||
if (this.collection.model.options.timestamps !== false) {
|
||||
// timestamps 相关字段不删除
|
||||
let timestampsFields = ['createdAt', 'updatedAt', 'deletedAt'];
|
||||
if (this.database.options.underscored) {
|
||||
timestampsFields = timestampsFields.map((field) => snakeCase(field));
|
||||
}
|
||||
if (timestampsFields.includes(this.columnName())) {
|
||||
this.collection.fields.delete(this.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 排序字段通过 sortable 控制
|
||||
const sortable = this.collection.options.sortable;
|
||||
if (sortable) {
|
||||
let sortField: any;
|
||||
if (sortable === true) {
|
||||
sortField = 'sort';
|
||||
} else if (typeof sortable === 'string') {
|
||||
sortField = sortable;
|
||||
} else if (sortable.name) {
|
||||
sortField = sortable.name || 'sort';
|
||||
}
|
||||
if (this.name === sortField) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.options.field && this.name !== this.options.field) {
|
||||
// // field 指向的是真实的字段名,如果与 name 不一样,说明字段只是引用
|
||||
// this.remove();
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (this.collection.isView()) {
|
||||
this.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
const columnReferencesCount = _.filter(
|
||||
this.collection.model.rawAttributes,
|
||||
(attr) => attr.field == this.columnName(),
|
||||
).length;
|
||||
|
||||
if (
|
||||
(await this.existsInDb({
|
||||
transaction: options?.transaction,
|
||||
})) &&
|
||||
columnReferencesCount == 1
|
||||
) {
|
||||
const queryInterface = this.database.sequelize.getQueryInterface();
|
||||
await queryInterface.removeColumn(this.collection.getTableNameWithSchema(), this.columnName(), options);
|
||||
}
|
||||
|
||||
this.remove();
|
||||
}
|
||||
|
||||
async existsInDb(options?: Transactionable) {
|
||||
const opts = {
|
||||
transaction: options?.transaction,
|
||||
|
@ -98,16 +98,12 @@ export class FieldModel extends MagicAttributeModel {
|
||||
|
||||
async remove(options?: any) {
|
||||
const collection = this.getFieldCollection();
|
||||
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
const field = collection.getField(this.get('name'));
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
|
||||
return field.removeFromDb({
|
||||
return collection.removeFieldFromDb(this.get('name'), {
|
||||
transaction: options.transaction,
|
||||
});
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ export default {
|
||||
});
|
||||
|
||||
const collection = db.getCollection(filterByTk);
|
||||
|
||||
await collection.sync({
|
||||
force: false,
|
||||
alter: {
|
||||
|
Loading…
Reference in New Issue
Block a user