fix: create empty collection (#1141)

* fix: create empty collection

* chore: comment

* chore: sqlite support

* chore: mysql support

* fix: collection api

* fix: error message
This commit is contained in:
ChengLei Shao 2022-11-24 18:16:01 +08:00 committed by GitHub
parent 78402c394b
commit 945c64304a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 0 deletions

View File

@ -17,6 +17,57 @@ describe('collection', () => {
afterEach(async () => {
await db.close();
});
it('should throw error when create empty collection in sqlite and mysql', async () => {
if (!db.inDialect('sqlite', 'mysql')) {
return;
}
db.collection({
name: 'empty',
timestamps: false,
autoGenId: false,
fields: [],
});
let error;
try {
await db.sync({
force: false,
alter: {
drop: false,
},
});
} catch (e) {
error = e;
}
expect(error.message.includes("Zero-column tables aren't supported in")).toBeTruthy();
});
it('can create empty collection', async () => {
if (db.inDialect('sqlite', 'mysql')) {
return;
}
db.collection({
name: 'empty',
timestamps: false,
autoGenId: false,
fields: [],
});
await db.sync({
force: false,
alter: {
drop: false,
},
});
expect(db.getCollection('empty')).toBeInstanceOf(Collection);
});
test('removeFromDb', async () => {
await db.clean({ drop: true });
const collection = db.collection({

View File

@ -459,7 +459,9 @@ export class Database extends EventEmitter implements AsyncEmitter {
if (isMySQL) {
await this.sequelize.query('SET FOREIGN_KEY_CHECKS = 0', null);
}
const result = await this.sequelize.sync(options);
if (isMySQL) {
await this.sequelize.query('SET FOREIGN_KEY_CHECKS = 1', null);
}

View File

@ -153,6 +153,15 @@ export class Model<TModelAttributes extends {} = any, TCreationAttributes extend
static async sync(options) {
const model = this as any;
// fix sequelize sync with model that not have any column
if (Object.keys(model.tableAttributes).length === 0) {
if (this.database.inDialect('sqlite', 'mysql')) {
throw new Error(`Zero-column tables aren't supported in ${this.database.sequelize.getDialect()}`);
}
options.alter = false;
}
if (this.collection.isInherited()) {
return SyncRunner.syncInheritModel(model, options);
}

View File

@ -75,6 +75,33 @@ describe('collections repository', () => {
await app.destroy();
});
it('should skip sync when create empty collection', async () => {
const response = await agent.resource('collections').create({
values: {
name: 'test',
autoGenId: false,
sortable: false,
timestamps: false,
},
});
expect(response.statusCode).toBe(200);
await agent.resource('fields').create({
values: {
name: 'field',
type: 'string',
collectionName: 'test',
},
});
const testCollection = app.db.getCollection('test');
const tableInfo = await app.db.sequelize.getQueryInterface().describeTable(testCollection.model.tableName);
expect(tableInfo['field']).toBeDefined();
});
it('should create collection without id', async () => {
const response = await agent.resource('collections').create({
values: {

View File

@ -87,6 +87,11 @@ export class CollectionModel extends MagicAttributeModel {
transaction: options?.transaction,
});
// @ts-ignore
if (Object.keys(collection.model.tableAttributes).length == 0) {
return;
}
try {
await collection.sync({
force: false,