Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create-column, update-column, version-column column kinds now support user specified values #5867

Merged
merged 4 commits into from Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -122,6 +122,7 @@
"test": "rimraf ./build && tsc && mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 60000 ./build/compiled/test",
"test-fast": "mocha --file ./build/compiled/test/utils/test-setup.js --bail --recursive --timeout 60000 ./build/compiled/test",
"compile": "rimraf ./build && tsc",
"watch": "./node_modules/.bin/tsc -w",
"package": "gulp package",
"lint": "tslint -p .",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 2"
Expand Down
9 changes: 5 additions & 4 deletions src/persistence/SubjectChangedColumnsComputer.ts
Expand Up @@ -40,10 +40,11 @@ export class SubjectChangedColumnsComputer {

// ignore special columns
if (column.isVirtual ||
column.isDiscriminator ||
column.isUpdateDate ||
column.isVersion ||
column.isCreateDate)
column.isDiscriminator // ||
// column.isUpdateDate ||
// column.isVersion ||
// column.isCreateDate
)
return;

const changeMap = subject.changeMaps.find(changeMap => changeMap.column === column);
Expand Down
3 changes: 2 additions & 1 deletion src/query-builder/InsertQueryBuilder.ts
Expand Up @@ -422,7 +422,8 @@ export class InsertQueryBuilder<Entity> extends QueryBuilder<Entity> {
}

// newly inserted entities always have a version equal to 1 (first version)
if (column.isVersion) {
// also, user-specified version must be empty
if (column.isVersion && value === undefined) {
expression += "1";

// } else if (column.isNestedSetLeft) {
Expand Down
96 changes: 96 additions & 0 deletions test/core/column-kinds/create-date-column/create-date-column.ts
@@ -0,0 +1,96 @@
import { expect } from "chai";
import "reflect-metadata";
import { Connection } from "../../../../src";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases,
sleep
} from "../../../utils/test-utils";
import { Post } from "./entity/Post";

describe("column kinds > create date column", () => {

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

it("create date column should automatically be set by a database", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// load and check if createdAt is a date (generated by db)
const loadedPost = await postRepository.findOne();
expect(loadedPost).to.be.not.empty;
expect(loadedPost!.title).to.be.eql("Post");
expect(loadedPost!.createdAt).to.be.instanceOf(Date);
})));

it("create date column can also be manually set by user", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

const createdAt = new Date(Date.parse("2020-01-01T00:00:00+0000"));

// save a new post
const post = new Post();
post.title = "Post";
post.createdAt = createdAt;
await postRepository.save(post);

// load and check if createdAt was a value set by us
const loadedPost = await postRepository.findOne();
expect(loadedPost).to.be.not.empty;
expect(loadedPost!.title).to.be.eql("Post");
expect(loadedPost!.createdAt).to.be.eql(createdAt);

})));

it("create date column should not be updated automatically on every change", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// load to get created date we had after first save
const loadedPostBeforeUpdate = await postRepository.findOne();

// wait a second
await sleep(1000);

// create post once again
post.title = "Updated Title";
await postRepository.save(post);

// check if date was created
const loadedPostAfterUpdate = await postRepository.findOne();
expect(loadedPostAfterUpdate!.createdAt.toString()).to.be.eql(loadedPostBeforeUpdate!.createdAt.toString());
})));

it("create date column should set a custom date when specified", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// create post once again
const createdAt = new Date(Date.parse("2020-01-01T00:00:00+0000"));
post.title = "Updated Title";
post.createdAt = createdAt;
await postRepository.save(post);

// check if date was created
const loadedPost = await postRepository.findOne();
expect(loadedPost!.createdAt).to.be.eql(createdAt);
})));
});
15 changes: 15 additions & 0 deletions test/core/column-kinds/create-date-column/entity/Post.ts
@@ -0,0 +1,15 @@
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from "../../../../../src";

@Entity()
export class Post {

@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;

@CreateDateColumn()
createdAt: Date;

}
15 changes: 15 additions & 0 deletions test/core/column-kinds/update-date-column/entity/Post.ts
@@ -0,0 +1,15 @@
import { Column, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from "../../../../../src";

@Entity()
export class Post {

@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;

@UpdateDateColumn()
updatedAt: Date;

}
115 changes: 115 additions & 0 deletions test/core/column-kinds/update-date-column/update-date-column.ts
@@ -0,0 +1,115 @@
import { expect } from "chai";
import "reflect-metadata";
import { Connection } from "../../../../src";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases,
sleep
} from "../../../utils/test-utils";
import { Post } from "./entity/Post";

describe("column kinds > update date column", () => {

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

it("update date column should automatically be set by a database", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// load and check if updatedAt is a date (generated by db)
const loadedPost = await postRepository.findOne();
expect(loadedPost).to.be.not.empty;
expect(loadedPost!.title).to.be.eql("Post");
expect(loadedPost!.updatedAt).to.be.instanceOf(Date);
})));

it("update column should not update if no changes were detected", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// update post once again
const loadedPost1 = await postRepository.findOneOrFail();
await postRepository.save(loadedPost1);

// load and check if version was a value set by us
const loadedPost2 = await postRepository.findOne();

// make sure version is the same
expect(loadedPost2!.title).to.be.eql("Post");
expect(loadedPost2!.updatedAt).to.be.eql(loadedPost1.updatedAt);
})));

it("update date column can also be manually set by user", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

const updatedAt = new Date(Date.parse("2020-01-01T00:00:00+0000"));

// save a new post
const post = new Post();
post.title = "Post";
post.updatedAt = updatedAt;
await postRepository.save(post);

// load and check if updatedAt was a value set by us
const loadedPost = await postRepository.findOne();
expect(loadedPost).to.be.not.empty;
expect(loadedPost!.title).to.be.eql("Post");
expect(loadedPost!.updatedAt).to.be.eql(updatedAt);
})));

it("update date column should be updated automatically on every change", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// load to get updated date we had after first save
const loadedPostBeforeUpdate = await postRepository.findOne();

// wait a second
await sleep(1000);

// update post once again
post.title = "Updated Title";
await postRepository.save(post);

// check if date was updated
const loadedPostAfterUpdate = await postRepository.findOne();
expect(loadedPostAfterUpdate!.updatedAt.toString()).to.be.not.eql(loadedPostBeforeUpdate!.updatedAt.toString());
})));

it("update date column should set a custom date when specified", () => Promise.all(connections.map(async connection => {
const postRepository = connection.getRepository(Post);

// save a new post
const post = new Post();
post.title = "Post";
await postRepository.save(post);

// update post once again
const updatedAt = new Date(Date.parse("2020-01-01T00:00:00+0000"));
post.title = "Updated Title";
post.updatedAt = updatedAt;
await postRepository.save(post);

// check if date was updated
const loadedPost = await postRepository.findOne();
expect(loadedPost!.updatedAt).to.be.eql(updatedAt);
})));
});
15 changes: 15 additions & 0 deletions test/core/column-kinds/version-column/entity/Post.ts
@@ -0,0 +1,15 @@
import { Column, Entity, PrimaryGeneratedColumn, VersionColumn } from "../../../../../src";

@Entity()
export class Post {

@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;

@VersionColumn()
version: number;

}