Skip to content

Commit

Permalink
fix(postgres): allow explicit schema name in prop.pivotTable
Browse files Browse the repository at this point in the history
Closes #2919
  • Loading branch information
B4nan committed Mar 19, 2022
1 parent 74751fb commit 1860ff5
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/knex/src/AbstractSqlConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export abstract class AbstractSqlConnection extends Connection {
}

protected createKnexClient(type: string): Knex {
return knex(this.getKnexOptions(type))
return knex<any, any>(this.getKnexOptions(type))
.on('query', data => {
if (!data.__knexQueryUid) {
this.logQuery(data.sql.toLowerCase().replace(/;$/, ''));
Expand Down
7 changes: 4 additions & 3 deletions packages/knex/src/query/QueryBuilderHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export class QueryBuilderHelper {
}

joinManyToManyReference(prop: EntityProperty, ownerAlias: string, alias: string, pivotAlias: string, type: 'leftJoin' | 'innerJoin' | 'pivotJoin', cond: Dictionary, path: string): Dictionary<JoinOptions> {
const meta = this.metadata.find(prop.pivotEntity)!;
const ret = {
[`${ownerAlias}.${prop.name}#${pivotAlias}`]: {
prop, type, cond, ownerAlias,
Expand All @@ -174,8 +175,8 @@ export class QueryBuilderHelper {
joinColumns: prop.joinColumns,
inverseJoinColumns: prop.inverseJoinColumns,
primaryKeys: prop.referencedColumnNames,
table: prop.pivotTable,
schema: this.driver.getSchemaName(this.metadata.find(prop.pivotEntity)),
table: meta.tableName,
schema: this.driver.getSchemaName(meta),
path: path.endsWith('[pivot]') ? path : `${path}[pivot]`,
} as JoinOptions,
};
Expand All @@ -184,7 +185,7 @@ export class QueryBuilderHelper {
return ret;
}

const prop2 = this.metadata.find(prop.pivotEntity)!.properties[prop.type + (prop.owner ? '_inverse' : '_owner')];
const prop2 = meta.properties[prop.type + (prop.owner ? '_inverse' : '_owner')];
ret[`${pivotAlias}.${prop2.name}#${alias}`] = this.joinManyToOneReference(prop2, pivotAlias, alias, type);
ret[`${pivotAlias}.${prop2.name}#${alias}`].path = path;

Expand Down
100 changes: 100 additions & 0 deletions tests/features/multiple-schemas/GH2919.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Collection, Entity, ManyToMany, MikroORM, PrimaryKey, Property, t } from '@mikro-orm/core';

@Entity({
schema: 'accounting',
tableName: 'account',
})
class Account {

@PrimaryKey({ type: t.bigint })
id!: string;

// eslint-disable-next-line @typescript-eslint/no-use-before-define
@ManyToMany({ entity: () => Customer, mappedBy: c => c.accounts })
customers: Collection<Customer> = new Collection<Customer>(this);

// eslint-disable-next-line @typescript-eslint/no-use-before-define
@ManyToMany({ entity: () => Company, mappedBy: c => c.accounts })
companies: Collection<Company> = new Collection<Company>(this);

}

@Entity({
schema: 'accounting',
tableName: 'customer',
})
class Customer {

@PrimaryKey({ type: t.bigint })
id!: string;

@Property()
name!: string;

@ManyToMany({
entity: () => Account,
pivotTable: 'accounting.customer_account',
joinColumn: 'customer_id',
inverseJoinColumn: 'account_id',
})
accounts = new Collection<Account>(this);

}

@Entity({
schema: 'accounting',
tableName: 'company',
})
class Company {

@PrimaryKey({ type: t.bigint })
id!: string;

@Property()
name!: string;

@ManyToMany({
entity: () => Account,
pivotTable: 'accounting.company_account',
joinColumn: 'company_id',
inverseJoinColumn: 'account_id',
})
accounts = new Collection<Account>(this);

}

describe('GH issue 2919', () => {

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [Account, Customer, Company],
dbName: 'mikro_orm_test_2919',
type: 'postgresql',
});
await orm.getSchemaGenerator().refreshDatabase();
});

afterAll(async () => {
await orm.close(true);
});

test(`GH issue 2919`, async () => {
const customer = new Customer();
customer.name = 'Customer 1';
customer.accounts.add(new Account(), new Account());
orm.em.persist(customer);

const company = new Company();
company.name = 'Company 1';
company.accounts.add(new Account());
await orm.em.fork().persist([customer, company]).flush();

const companyAccounts = await orm.em.find(Account, {
companies: { name: 'Company 1' },
});
expect(companyAccounts).toHaveLength(1);
});

});

0 comments on commit 1860ff5

Please sign in to comment.