Skip to content

Commit

Permalink
fix(core): ensure partial loading respects advanced mapped type methods
Browse files Browse the repository at this point in the history
Closes #4622
  • Loading branch information
B4nan committed Aug 25, 2023
1 parent 539557b commit 72554fd
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 15 deletions.
11 changes: 2 additions & 9 deletions packages/knex/src/AbstractSqlDriver.ts
Expand Up @@ -935,7 +935,7 @@ export abstract class AbstractSqlDriver<Connection extends AbstractSqlConnection

if (prop.reference === ReferenceType.EMBEDDED) {
if (prop.object) {
ret.push(prop.fieldNames[0]);
ret.push(prop.name);
return;
}

Expand All @@ -951,14 +951,7 @@ export abstract class AbstractSqlDriver<Connection extends AbstractSqlConnection
return;
}

if (prop.formula) {
ret.push(prop.name);
return;
}

if (prop.fieldNames) {
ret.push(...prop.fieldNames);
}
ret.push(prop.name);
}

protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T>, fields?: Field<T>[]): Field<T>[] {
Expand Down
5 changes: 5 additions & 0 deletions packages/knex/src/query/QueryBuilder.ts
Expand Up @@ -898,6 +898,11 @@ export class QueryBuilder<T extends object = AnyEntity> {
return;
}

if (prop && prop.fieldNames.length > 1) {
ret.push(...prop.fieldNames.map(f => this.helper.mapper(f, this.type) as string));
return;
}

ret.push(this.helper.mapper(field, this.type) as string);
});

Expand Down
6 changes: 0 additions & 6 deletions tests/QueryBuilder.test.ts
Expand Up @@ -2972,12 +2972,6 @@ describe('QueryBuilder', () => {
'from `book2` as `b` ' +
'left join `book2_tags` as `e1` on `b`.`uuid_pk` = `e1`.`book2_uuid_pk` ' +
'left join `book_tag2` as `t` on `e1`.`book_tag2_id` = `t`.`id` and `t`.`name` = \'t1\'');

// const sql2 = orm.em.createQueryBuilder(Book2, 'b')
// .select('*')
// .joinAndSelect('author', 'a', { 'a.born': new Date('1990-03-23') })
// .getFormattedQuery();
// expect(sql2).toBe("select `b`.*, `a`.`id` as `a__id`, `a`.`created_at` as `a__created_at`, `a`.`updated_at` as `a__updated_at`, `a`.`name` as `a__name`, `a`.`email` as `a__email`, `a`.`age` as `a__age`, `a`.`terms_accepted` as `a__terms_accepted`, `a`.`optional` as `a__optional`, `a`.`identities` as `a__identities`, `a`.`born` as `a__born`, `a`.`born_time` as `a__born_time`, `a`.`favourite_book_uuid_pk` as `a__favourite_book_uuid_pk`, `a`.`favourite_author_id` as `a__favourite_author_id`, `b`.price * 1.19 as `price_taxed` from `book2` as `b` inner join `author2` as `a` on `b`.`author_id` = `a`.`id` and `a`.`born` = '1990-03-23'");
});

test('sub-query order-by fields are always fully qualified', () => {
Expand Down
23 changes: 23 additions & 0 deletions tests/features/custom-types/custom-types.mysql.test.ts
Expand Up @@ -168,6 +168,29 @@ describe('custom types [mysql]', () => {
expect(meta.properties.extendedPoint.customType).toBeInstanceOf(ExtendedPointType);
});

test('partial loading with custom types (gh issue 4622)', async () => {
const mock = mockLogger(orm, ['query']);

const loc = new Location();
const addr = new Address(loc);
loc.point = new Point(1.23, 4.56);
loc.extendedPoint = new Point(5.23, 9.56);
await orm.em.persistAndFlush(addr);
orm.em.clear();

const l1 = await orm.em.findOneOrFail(Location, loc, { fields: ['point', 'extendedPoint'] });
expect(l1.point).toBeInstanceOf(Point);
expect(l1.point).toMatchObject({ latitude: 1.23, longitude: 4.56 });
expect(l1.extendedPoint).toBeInstanceOf(Point);
expect(l1.extendedPoint).toMatchObject({ latitude: 5.23, longitude: 9.56 });
expect(mock.mock.calls[0][0]).toMatch('begin');
expect(mock.mock.calls[1][0]).toMatch('insert into `location` (`point`, `extended_point`) values (ST_PointFromText(?), ST_PointFromText(?))');
expect(mock.mock.calls[2][0]).toMatch('insert into `address` (`location_id`) values (?)');
expect(mock.mock.calls[3][0]).toMatch('commit');
expect(mock.mock.calls[4][0]).toMatch('select `l0`.`id`, ST_AsText(`l0`.`point`) as `point`, ST_AsText(`l0`.`extended_point`) as `extended_point` from `location` as `l0` where `l0`.`id` = ? limit ?');
expect(mock.mock.calls).toHaveLength(5);
});

test('create and update many records with custom types (gh issue 1625)', async () => {
const mock = mockLogger(orm, ['query', 'query-params']);

Expand Down

0 comments on commit 72554fd

Please sign in to comment.