Skip to content

Commit

Permalink
fix: Buffer in primary columns causes bugs with relations (#7952)
Browse files Browse the repository at this point in the history
* fixed using Buffer in relations

* removed console.log

* added test for #4060
  • Loading branch information
AlexMesser committed Jul 24, 2021
1 parent 29f1f86 commit 37e08a7
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 25 deletions.
8 changes: 4 additions & 4 deletions src/metadata/ColumnMetadata.ts
Expand Up @@ -612,10 +612,10 @@ export class ColumnMetadata {
if (embeddedObject) {
if (this.relationMetadata && this.referencedColumn) {
const relatedEntity = this.relationMetadata.getEntityValue(embeddedObject);
if (relatedEntity && relatedEntity instanceof Object && !(relatedEntity instanceof FindOperator)) {
if (relatedEntity && relatedEntity instanceof Object && !(relatedEntity instanceof FindOperator) && !(relatedEntity instanceof Buffer)) {
value = this.referencedColumn.getEntityValue(relatedEntity);

} else if (embeddedObject[this.propertyName] && embeddedObject[this.propertyName] instanceof Object && !(embeddedObject[this.propertyName] instanceof FindOperator)) {
} else if (embeddedObject[this.propertyName] && embeddedObject[this.propertyName] instanceof Object && !(embeddedObject[this.propertyName] instanceof FindOperator) && !(embeddedObject[this.propertyName] instanceof Buffer)) {
value = this.referencedColumn.getEntityValue(embeddedObject[this.propertyName]);

} else {
Expand All @@ -636,10 +636,10 @@ export class ColumnMetadata {
} else { // no embeds - no problems. Simply return column name by property name of the entity
if (this.relationMetadata && this.referencedColumn) {
const relatedEntity = this.relationMetadata.getEntityValue(entity);
if (relatedEntity && relatedEntity instanceof Object && !(relatedEntity instanceof FindOperator) && !(relatedEntity instanceof Function)) {
if (relatedEntity && relatedEntity instanceof Object && !(relatedEntity instanceof FindOperator) && !(relatedEntity instanceof Function) && !(relatedEntity instanceof Buffer)) {
value = this.referencedColumn.getEntityValue(relatedEntity);

} else if (entity[this.propertyName] && entity[this.propertyName] instanceof Object && !(entity[this.propertyName] instanceof FindOperator) && !(entity[this.propertyName] instanceof Function)) {
} else if (entity[this.propertyName] && entity[this.propertyName] instanceof Object && !(entity[this.propertyName] instanceof FindOperator) && !(entity[this.propertyName] instanceof Function) && !(entity[this.propertyName] instanceof Buffer)) {
value = this.referencedColumn.getEntityValue(entity[this.propertyName]);

} else {
Expand Down
2 changes: 1 addition & 1 deletion src/persistence/Subject.ts
Expand Up @@ -248,7 +248,7 @@ export class Subject {
// or value can be a null or direct relation id, e.g. post.question = 1
// if its a direction relation id then we just set it to the valueMap,
// however if its an object then we need to extract its relation id map and set it to the valueMap
if (value instanceof Object) {
if (value instanceof Object && !(value instanceof Buffer)) {

// get relation id, e.g. referenced column name and its value,
// for example: { id: 1 } which then will be set to relation, e.g. post.category = { id: 1 }
Expand Down
11 changes: 9 additions & 2 deletions src/persistence/SubjectChangedColumnsComputer.ts
Expand Up @@ -128,8 +128,15 @@ export class SubjectChangedColumnsComputer {
}

// if value is not changed - then do nothing
if (normalizedValue === databaseValue)
return;
if (normalizedValue instanceof Buffer && databaseValue instanceof Buffer) {
if (normalizedValue.equals(databaseValue)) {
return;
}

} else {
if (normalizedValue === databaseValue)
return;
}
}
subject.diffColumns.push(column);
subject.changeMaps.push({
Expand Down
5 changes: 2 additions & 3 deletions src/query-builder/UpdateQueryBuilder.ts
Expand Up @@ -403,10 +403,9 @@ export class UpdateQueryBuilder<Entity> extends QueryBuilder<Entity> implements

//
let value = column.getEntityValue(valuesSet);
if (column.referencedColumn && value instanceof Object) {
if (column.referencedColumn && value instanceof Object && !(value instanceof Buffer)) {
value = column.referencedColumn.getEntityValue(value);
}
else if (!(value instanceof Function)) {
} else if (!(value instanceof Function)) {
value = this.connection.driver.preparePersistentValue(value, column);
}

Expand Down
15 changes: 15 additions & 0 deletions test/github-issues/4060/entity/Bar.ts
@@ -0,0 +1,15 @@
import {Column, Entity, JoinColumn, OneToOne, PrimaryColumn} from "../../../../src";
import {Foo} from "./Foo";

@Entity()
export class Bar {
@PrimaryColumn({ type: "varbinary", length: 16 })
id: Buffer;

@Column()
name: string;

@OneToOne(() => Foo)
@JoinColumn({ name: "id", referencedColumnName: "id" })
foo: Foo;
}
10 changes: 10 additions & 0 deletions test/github-issues/4060/entity/Foo.ts
@@ -0,0 +1,10 @@
import {Column, Entity, PrimaryColumn} from "../../../../src";

@Entity()
export class Foo {
@PrimaryColumn({ type: "varbinary", length: 16 })
id: Buffer;

@Column()
name: string;
}
36 changes: 36 additions & 0 deletions test/github-issues/4060/issue-4060.ts
@@ -0,0 +1,36 @@
import { expect } from "chai";
import { Connection } from "../../../src";
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
import {Foo} from "./entity/Foo";
import {Bar} from "./entity/Bar";

describe("github issues > #4060 Fail to insert entity with Buffer type of primary column under some circumstances.", () => {

let connections: Connection[];
before(async () => {
connections = await createTestingConnections({
enabledDrivers: ["mysql", "mariadb"],
entities: [Foo, Bar],
schemaCreate: true,
dropSchema: true
});
});
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

it("should save entities", () => Promise.all(connections.map(async connection => {
const id = Buffer.from("foobar");
const foo = new Foo();
foo.id = id;
foo.name = "foo";
await connection.manager.save(foo);

const bar = new Bar();
bar.id = id;
bar.name = "bar";
await connection.manager.save(bar);

expect(foo).to.exist;
expect(bar).to.exist;
})));
});
22 changes: 10 additions & 12 deletions test/github-issues/7851/issue-7851.ts
@@ -1,12 +1,10 @@

import { expect } from "chai";
import { Connection } from "../../../src";
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
import { User } from "./entity/user";
import { Message } from "./entity/message";


describe.skip("github issues > #7851 Updating (using save method) a ManyToOne relation sets the object.relation_id to null", () => {
describe("github issues > #7851 Updating (using save method) a ManyToOne relation sets the object.relation_id to null", () => {

let connections: Connection[];
before(async () => {
Expand All @@ -28,30 +26,30 @@ describe.skip("github issues > #7851 Updating (using save method) a ManyToOne re
const user1ID = Buffer.from([135,114,221,160,230,218,17,234,175,15,4,237,51,12,208,0]);
const user2ID = Buffer.from([50,114,221,160,230,218,17,234,175,15,4,237,51,12,208,0]);
const messageID = Buffer.from([64,114,221,160,230,218,17,234,175,15,4,237,51,12,208,0]);

// Inserting users, works fine

const user1: User = {
id: user1ID,
};

const user2: User = {
id: user2ID,
};

await userRepository.save([user1, user2]);

// Inserting message : works fine

const message: Message = {
id: messageID,
sender: user1,
};

await messageRepository.save(message);

// Updating message.sender

message.sender = user2;
await messageRepository.save(message);

Expand All @@ -63,4 +61,4 @@ describe.skip("github issues > #7851 Updating (using save method) a ManyToOne re
expect(savedMessage.sender).to.be.instanceOf(User);
expect(savedMessage.sender.id).to.be.eql(user2ID);
})));
});
});
4 changes: 1 addition & 3 deletions test/github-issues/7852/issue-7852.ts
Expand Up @@ -4,9 +4,7 @@ import { closeTestingConnections, createTestingConnections, reloadTestingDatabas
import { User } from "./entity/user";
import { UsersObject } from "./entity/usersObject";


describe.skip("github issues > #7852 saving a ManyToMany relation tries to insert (DEFAULT, entity2.id) \
instead of (entity1.id, entity2.id), when id is Buffer", () => {
describe("github issues > #7852 saving a ManyToMany relation tries to insert (DEFAULT, entity2.id) instead of (entity1.id, entity2.id), when id is Buffer", () => {

let connections: Connection[];
before(async () => {
Expand Down

0 comments on commit 37e08a7

Please sign in to comment.