Skip to content

Commit

Permalink
fix: don't transform json(b) column value when computing update changes
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitryvolkov committed Oct 17, 2020
1 parent dee1758 commit 16c962b
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/persistence/SubjectChangedColumnsComputer.ts
Expand Up @@ -61,9 +61,11 @@ export class SubjectChangedColumnsComputer {

// if there is no database entity then all columns are treated as new, e.g. changed
if (subject.databaseEntity) {
// skip transform database value for json / jsonb for comparison later on
const shouldTransformDatabaseEntity = column.type !== "json" && column.type !== "jsonb";

// get database value of the column
let databaseValue = column.getEntityValue(subject.databaseEntity, true);
let databaseValue = column.getEntityValue(subject.databaseEntity, shouldTransformDatabaseEntity);

// filter out "relational columns" only in the case if there is a relation object in entity
if (column.relationMetadata) {
Expand Down
@@ -0,0 +1,17 @@
import { Entity } from "../../../../src/decorator/entity/Entity";
import { Column } from "../../../../src/decorator/columns/Column";
import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn";
import { VersionColumn } from "../../../../src";
import { testTransformer } from "../test-transformer";

@Entity()
export class DummyJSONEntity {
@PrimaryGeneratedColumn()
id: number;

@VersionColumn()
version: number;

@Column({ type: "json", transformer: testTransformer })
value: Record<string, any>;
}
@@ -0,0 +1,17 @@
import { Entity } from "../../../../src/decorator/entity/Entity";
import { Column } from "../../../../src/decorator/columns/Column";
import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn";
import { VersionColumn } from "../../../../src";
import { testTransformer } from "../test-transformer";

@Entity()
export class DummyJSONBEntity {
@PrimaryGeneratedColumn()
id: number;

@VersionColumn()
version: number;

@Column({ type: "jsonb", transformer: testTransformer })
value: Record<string, any>;
}
@@ -0,0 +1,14 @@
export const testTransformer = {
to(data: any) {
if ("secretProperty" in data) {
data.secretProperty = `secret-${data.secretProperty}`;
}
return data;
},
from(data: any) {
if ("secretProperty" in data) {
data.secretProperty = data.secretProperty.split("-")[1];
}
return data;
}
};
@@ -0,0 +1,53 @@
import "reflect-metadata";
import { createTestingConnections, closeTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
import { Connection } from "../../../src/connection/Connection";
import { expect } from "chai";
import { DummyJSONEntity } from "./entity/json-entity";
import { DummyJSONBEntity } from "./entity/jsonb-entity";

describe("other issues > correctly compute change for transformed json / jsonb columns", () => {

let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchema: true,
enabledDrivers: ["postgres"]
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

it("should not update entity if transformed JSON column did not change", () => Promise.all(connections.map(async connection => {
const repository = connection.getRepository(DummyJSONEntity);

const dummy = repository.create({
value: {
secretProperty: "hello"
},
});

await repository.save(dummy);

await repository.save(dummy);

const dummyEntity = await repository.findOneOrFail(dummy.id);
expect(dummyEntity.version).to.equal(1);
})));

it("should not update entity if transformed JSONB column did not change", () => Promise.all(connections.map(async connection => {
const repository = connection.getRepository(DummyJSONBEntity);

const dummy = repository.create({
value: {
secretProperty: "hello"
},
});

await repository.save(dummy);

await repository.save(dummy);

const dummyEntity = await repository.findOneOrFail(dummy.id);
expect(dummyEntity.version).to.equal(1);
})));
});

0 comments on commit 16c962b

Please sign in to comment.