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 { IdentifierError } from '../errors/identifier-error';
 | 
			
		||||
 | 
			
		||||
const pgOnly = () => (process.env.DB_DIALECT == 'postgres' ? it : it.skip);
 | 
			
		||||
describe('collection', () => {
 | 
			
		||||
  let db: Database;
 | 
			
		||||
 | 
			
		||||
@ -46,11 +47,7 @@ describe('collection', () => {
 | 
			
		||||
    expect(error.message.includes("Zero-column tables aren't supported in")).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('can create empty collection', async () => {
 | 
			
		||||
    if (db.inDialect('sqlite', 'mysql')) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  pgOnly()('can create empty collection', async () => {
 | 
			
		||||
    db.collection({
 | 
			
		||||
      name: 'empty',
 | 
			
		||||
      timestamps: false,
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,49 @@ pgOnly()('collection inherits', () => {
 | 
			
		||||
    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 () => {
 | 
			
		||||
    db.collection({
 | 
			
		||||
      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()}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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()) {
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,7 @@ export class SyncRunner {
 | 
			
		||||
            transaction,
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const sequenceCurrentVal = parseInt(sequenceCurrentValResult[0][0]['last_value']);
 | 
			
		||||
 | 
			
		||||
        if (sequenceCurrentVal > maxSequenceVal) {
 | 
			
		||||
@ -89,12 +90,20 @@ export class SyncRunner {
 | 
			
		||||
      const sequenceTables = [...parentsDeep, tableName];
 | 
			
		||||
 | 
			
		||||
      for (const sequenceTable of sequenceTables) {
 | 
			
		||||
        await queryInterface.sequelize.query(
 | 
			
		||||
          `alter table "${sequenceTable}" alter column id set default nextval('${maxSequenceName}')`,
 | 
			
		||||
          {
 | 
			
		||||
            transaction,
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
        try {
 | 
			
		||||
          await queryInterface.sequelize.query(
 | 
			
		||||
            `alter table "${sequenceTable}" alter column id set default nextval('${maxSequenceName}')`,
 | 
			
		||||
            {
 | 
			
		||||
              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,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // postgres support zero column table, other database should not sync it to database
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    if (Object.keys(collection.model.tableAttributes).length == 0) {
 | 
			
		||||
    if (Object.keys(collection.model.tableAttributes).length == 0 && !this.db.inDialect('postgres')) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user