fix: create inherits with empty table (#1160)
* chore: test * feat: patch to queryInterface.describeTable * test: add field to empty collection * fix: create inherits with parent dose not have id field * fix: test * fix: test
This commit is contained in:
parent
205fafcd4a
commit
1764b53a9b
@ -3,6 +3,7 @@ import { Database } from '../database';
|
|||||||
import { mockDatabase } from './index';
|
import { mockDatabase } from './index';
|
||||||
import { IdentifierError } from '../errors/identifier-error';
|
import { IdentifierError } from '../errors/identifier-error';
|
||||||
|
|
||||||
|
const pgOnly = () => (process.env.DB_DIALECT == 'postgres' ? it : it.skip);
|
||||||
describe('collection', () => {
|
describe('collection', () => {
|
||||||
let db: Database;
|
let db: Database;
|
||||||
|
|
||||||
@ -46,11 +47,7 @@ describe('collection', () => {
|
|||||||
expect(error.message.includes("Zero-column tables aren't supported in")).toBeTruthy();
|
expect(error.message.includes("Zero-column tables aren't supported in")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can create empty collection', async () => {
|
pgOnly()('can create empty collection', async () => {
|
||||||
if (db.inDialect('sqlite', 'mysql')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.collection({
|
db.collection({
|
||||||
name: 'empty',
|
name: 'empty',
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
|
@ -15,6 +15,49 @@ pgOnly()('collection inherits', () => {
|
|||||||
await db.close();
|
await db.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create inherits from empty table', async () => {
|
||||||
|
const empty = db.collection({
|
||||||
|
name: 'empty',
|
||||||
|
timestamps: false,
|
||||||
|
autoGenId: false,
|
||||||
|
fields: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.sync({
|
||||||
|
force: false,
|
||||||
|
alter: {
|
||||||
|
drop: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const parent2 = db.collection({
|
||||||
|
name: 'parent2',
|
||||||
|
});
|
||||||
|
|
||||||
|
const inherits = db.collection({
|
||||||
|
name: 'inherits',
|
||||||
|
inherits: ['empty', 'parent2'],
|
||||||
|
fields: [{ type: 'string', name: 'name' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.sync({
|
||||||
|
force: false,
|
||||||
|
alter: {
|
||||||
|
drop: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(inherits instanceof InheritedCollection).toBeTruthy();
|
||||||
|
|
||||||
|
const record = await inherits.repository.create({
|
||||||
|
values: {
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(record.get('name')).toEqual('test');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not throw error when fields have same type with parent', async () => {
|
it('should not throw error when fields have same type with parent', async () => {
|
||||||
db.collection({
|
db.collection({
|
||||||
name: 'parent',
|
name: 'parent',
|
||||||
|
@ -159,7 +159,24 @@ export class Model<TModelAttributes extends {} = any, TCreationAttributes extend
|
|||||||
throw new Error(`Zero-column tables aren't supported in ${this.database.sequelize.getDialect()}`);
|
throw new Error(`Zero-column tables aren't supported in ${this.database.sequelize.getDialect()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.alter = false;
|
// @ts-ignore
|
||||||
|
const queryInterface = this.sequelize.queryInterface;
|
||||||
|
|
||||||
|
if (!queryInterface.patched) {
|
||||||
|
const oldDescribeTable = queryInterface.describeTable;
|
||||||
|
queryInterface.describeTable = async function (...args) {
|
||||||
|
try {
|
||||||
|
return await oldDescribeTable.call(this, ...args);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.includes('No description found for')) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
queryInterface.patched = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.collection.isInherited()) {
|
if (this.collection.isInherited()) {
|
||||||
|
@ -70,6 +70,7 @@ export class SyncRunner {
|
|||||||
transaction,
|
transaction,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const sequenceCurrentVal = parseInt(sequenceCurrentValResult[0][0]['last_value']);
|
const sequenceCurrentVal = parseInt(sequenceCurrentValResult[0][0]['last_value']);
|
||||||
|
|
||||||
if (sequenceCurrentVal > maxSequenceVal) {
|
if (sequenceCurrentVal > maxSequenceVal) {
|
||||||
@ -89,12 +90,20 @@ export class SyncRunner {
|
|||||||
const sequenceTables = [...parentsDeep, tableName];
|
const sequenceTables = [...parentsDeep, tableName];
|
||||||
|
|
||||||
for (const sequenceTable of sequenceTables) {
|
for (const sequenceTable of sequenceTables) {
|
||||||
await queryInterface.sequelize.query(
|
try {
|
||||||
`alter table "${sequenceTable}" alter column id set default nextval('${maxSequenceName}')`,
|
await queryInterface.sequelize.query(
|
||||||
{
|
`alter table "${sequenceTable}" alter column id set default nextval('${maxSequenceName}')`,
|
||||||
transaction,
|
{
|
||||||
},
|
transaction,
|
||||||
);
|
},
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.match(/column "id" of relation "\w+" does not exist/)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,8 +87,9 @@ export class CollectionModel extends MagicAttributeModel {
|
|||||||
transaction: options?.transaction,
|
transaction: options?.transaction,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// postgres support zero column table, other database should not sync it to database
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (Object.keys(collection.model.tableAttributes).length == 0) {
|
if (Object.keys(collection.model.tableAttributes).length == 0 && !this.db.inDialect('postgres')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user