added testing configuration;

working on tests;
This commit is contained in:
Zotov Dmitry 2019-02-08 18:43:50 +05:00
parent 9f6704e2e8
commit d28f74c1ad
10 changed files with 132 additions and 16 deletions

View File

@ -61,6 +61,13 @@ services:
SA_PASSWORD: "Admin12345"
ACCEPT_EULA: "Y"
# cockroachdb
cockroachdb:
image: "cockroachdb/cockroach:v2.1.4"
container_name: "typeorm-cockroachdb"
ports:
- "26257:26257"
# mongodb
mongodb:
image: "mongo:3.4.18"

View File

@ -60,6 +60,16 @@
"port": 1521,
"sid": "xe.oracle.docker"
},
{
"skip": false,
"name": "cockroachdb",
"type": "cockroachdb",
"host": "localhost",
"port": 26257,
"username": "root",
"password": "",
"database": "defaultdb"
},
{
"skip": false,
"disabledIfNotEnabledImplicitly": true,

View File

@ -1,3 +1,4 @@
import {CockroachDriver} from "../driver/cockroachdb/CockroachDriver";
import {EntityMetadata} from "../metadata/EntityMetadata";
import {ColumnMetadata} from "../metadata/ColumnMetadata";
import {IndexMetadata} from "../metadata/IndexMetadata";
@ -443,9 +444,6 @@ export class EntityMetadataBuilder {
return new RelationCountMetadata({ entityMetadata, args });
});
entityMetadata.ownIndices = this.metadataArgsStorage.filterIndices(entityMetadata.inheritanceTree).map(args => {
return new IndexMetadata({ entityMetadata, args });
});
entityMetadata.ownListeners = this.metadataArgsStorage.filterListeners(entityMetadata.inheritanceTree).map(args => {
return new EntityListenerMetadata({ entityMetadata: entityMetadata, args: args });
});
@ -460,6 +458,33 @@ export class EntityMetadataBuilder {
});
}
// Mysql stores unique indices constraints as unique constrains.
if (this.connection.driver instanceof CockroachDriver) {
entityMetadata.ownIndices = this.metadataArgsStorage.filterIndices(entityMetadata.inheritanceTree)
.filter(args => !args.unique)
.map(args => {
return new IndexMetadata({entityMetadata, args});
});
const uniques = this.metadataArgsStorage.filterIndices(entityMetadata.inheritanceTree)
.filter(args => args.unique)
.map(args => {
return new UniqueMetadata({
entityMetadata: entityMetadata,
args: {
target: args.target,
columns: args.columns,
}
});
});
entityMetadata.uniques.push(...uniques);
} else {
entityMetadata.ownIndices = this.metadataArgsStorage.filterIndices(entityMetadata.inheritanceTree).map(args => {
return new IndexMetadata({entityMetadata, args});
});
}
// Mysql stores unique constraints as unique indices.
if (this.connection.driver instanceof MysqlDriver) {
const indices = this.metadataArgsStorage.filterUniques(entityMetadata.inheritanceTree).map(args => {
@ -477,9 +502,10 @@ export class EntityMetadataBuilder {
entityMetadata.ownIndices.push(...indices);
} else {
entityMetadata.uniques = this.metadataArgsStorage.filterUniques(entityMetadata.inheritanceTree).map(args => {
const uniques = this.metadataArgsStorage.filterUniques(entityMetadata.inheritanceTree).map(args => {
return new UniqueMetadata({ entityMetadata, args });
});
entityMetadata.uniques.push(...uniques);
}
}

View File

@ -1,3 +1,4 @@
import {CockroachDriver} from "../driver/cockroachdb/CockroachDriver";
import {Table} from "./table/Table";
import {TableColumn} from "./table/TableColumn";
import {TableForeignKey} from "./table/TableForeignKey";
@ -59,7 +60,10 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
*/
async build(): Promise<void> {
this.queryRunner = this.connection.createQueryRunner("master");
await this.queryRunner.startTransaction();
// CockroachDB implements asynchronous schema sync operations which can not been executed in transaction.
// E.g. if you try to DROP column and ADD it again in the same transaction, crdb throws error.
if (!(this.connection.driver instanceof CockroachDriver))
await this.queryRunner.startTransaction();
try {
const tablePaths = this.entityToSyncMetadatas.map(metadata => metadata.tablePath);
await this.queryRunner.getTables(tablePaths);
@ -69,12 +73,14 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
if (this.connection.queryResultCache)
await this.connection.queryResultCache.synchronize(this.queryRunner);
await this.queryRunner.commitTransaction();
if (!(this.connection.driver instanceof CockroachDriver))
await this.queryRunner.commitTransaction();
} catch (error) {
try { // we throw original error even if rollback thrown an error
await this.queryRunner.rollbackTransaction();
if (!(this.connection.driver instanceof CockroachDriver))
await this.queryRunner.rollbackTransaction();
} catch (rollbackError) { }
throw error;

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {closeTestingConnections, createTestingConnections} from "../../utils/test-utils";
import {ColumnMetadata} from "../../../src/metadata/ColumnMetadata";
import {ColumnMetadataArgs} from "../../../src/metadata-args/ColumnMetadataArgs";
@ -31,7 +32,7 @@ describe("schema builder > add column", () => {
options: {
type: "int",
name: "secondId",
primary: true,
primary: !(connection.driver instanceof CockroachDriver), // CockroachDB does not allow changing pk
nullable: false
}
}
@ -62,8 +63,9 @@ describe("schema builder > add column", () => {
const table = await queryRunner.getTable("post");
const column1 = table!.findColumnByName("secondId")!;
column1.should.be.exist;
column1.isPrimary.should.be.true;
column1.isNullable.should.be.false;
if (!(connection.driver instanceof CockroachDriver))
column1.isPrimary.should.be.true;
const column2 = table!.findColumnByName("description")!;
column2.should.be.exist;

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {expect} from "chai";
import {PromiseUtils} from "../../../src";
@ -72,6 +73,11 @@ describe("schema builder > change column", () => {
}));
it("should correctly change column type", () => PromiseUtils.runInSequence(connections, async connection => {
// TODO: https://github.com/cockroachdb/cockroach/issues/34710
if (connection.driver instanceof CockroachDriver)
return;
const postMetadata = connection.getMetadata(Post);
const versionColumn = postMetadata.findColumnWithPropertyName("version")!;
versionColumn.type = "int";
@ -95,6 +101,10 @@ describe("schema builder > change column", () => {
}));
it("should correctly make column primary and generated", () => PromiseUtils.runInSequence(connections, async connection => {
// CockroachDB does not allow changing PK
if (connection.driver instanceof CockroachDriver)
return;
const postMetadata = connection.getMetadata(Post);
const idColumn = postMetadata.findColumnWithPropertyName("id")!;
const versionColumn = postMetadata.findColumnWithPropertyName("version")!;
@ -147,6 +157,10 @@ describe("schema builder > change column", () => {
}));
it("should correctly change non-generated column on to uuid-generated column", () => PromiseUtils.runInSequence(connections, async connection => {
// CockroachDB does not allow changing PK
if (connection.driver instanceof CockroachDriver)
return;
const queryRunner = connection.createQueryRunner();
if (connection.driver instanceof PostgresDriver)
@ -158,7 +172,7 @@ describe("schema builder > change column", () => {
idColumn.generationStrategy = "uuid";
// depending on driver, we must change column and referenced column types
if (connection.driver instanceof PostgresDriver) {
if (connection.driver instanceof PostgresDriver || connection.driver instanceof CockroachDriver) {
idColumn.type = "uuid";
} else if (connection.driver instanceof SqlServerDriver) {
idColumn.type = "uniqueidentifier";
@ -171,7 +185,7 @@ describe("schema builder > change column", () => {
const postTable = await queryRunner.getTable("post");
await queryRunner.release();
if (connection.driver instanceof PostgresDriver || connection.driver instanceof SqlServerDriver) {
if (connection.driver instanceof PostgresDriver || connection.driver instanceof SqlServerDriver || connection.driver instanceof CockroachDriver) {
postTable!.findColumnByName("id")!.isGenerated.should.be.true;
postTable!.findColumnByName("id")!.generationStrategy!.should.be.equal("uuid");
@ -191,6 +205,10 @@ describe("schema builder > change column", () => {
}));
it("should correctly change generated column generation strategy", () => PromiseUtils.runInSequence(connections, async connection => {
// CockroachDB does not allow changing PK
if (connection.driver instanceof CockroachDriver)
return;
const teacherMetadata = connection.getMetadata("teacher");
const studentMetadata = connection.getMetadata("student");
const idColumn = teacherMetadata.findColumnWithPropertyName("id")!;
@ -198,7 +216,7 @@ describe("schema builder > change column", () => {
idColumn.generationStrategy = "uuid";
// depending on driver, we must change column and referenced column types
if (connection.driver instanceof PostgresDriver) {
if (connection.driver instanceof PostgresDriver || connection.driver instanceof CockroachDriver) {
idColumn.type = "uuid";
teacherColumn.type = "uuid";
} else if (connection.driver instanceof SqlServerDriver) {

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {PromiseUtils} from "../../../src";
import {IndexMetadata} from "../../../src/metadata/IndexMetadata";
@ -74,6 +75,8 @@ describe("schema builder > change index", () => {
it("should ignore index synchronization when `synchronize` set to false", () => PromiseUtils.runInSequence(connections, async connection => {
// You can not disable synchronization for unique index in CockroachDB, because unique indices are stored as UNIQUE constraints
const queryRunner = connection.createQueryRunner();
let teacherTable = await queryRunner.getTable("teacher");
teacherTable!.indices.length.should.be.equal(0);
@ -82,14 +85,28 @@ describe("schema builder > change index", () => {
await queryRunner.createIndex(teacherTable!, index);
teacherTable = await queryRunner.getTable("teacher");
teacherTable!.indices.length.should.be.equal(1);
teacherTable!.indices[0].isUnique!.should.be.true;
// CockroachDB stores unique indices as UNIQUE constraints
if (connection.driver instanceof CockroachDriver) {
teacherTable!.indices.length.should.be.equal(0);
teacherTable!.uniques.length.should.be.equal(1);
teacherTable!.findColumnByName("name")!.isUnique.should.be.true;
} else {
teacherTable!.indices.length.should.be.equal(1);
teacherTable!.indices[0].isUnique!.should.be.true;
}
await connection.synchronize();
teacherTable = await queryRunner.getTable("teacher");
teacherTable!.indices.length.should.be.equal(1);
teacherTable!.indices[0].isUnique!.should.be.true;
// CockroachDB stores unique indices as UNIQUE constraints
if (connection.driver instanceof CockroachDriver) {
teacherTable!.indices.length.should.be.equal(0);
teacherTable!.uniques.length.should.be.equal(0);
teacherTable!.findColumnByName("name")!.isUnique.should.be.false;
} else {
teacherTable!.indices.length.should.be.equal(1);
teacherTable!.indices[0].isUnique!.should.be.true;
}
await queryRunner.release();

View File

@ -1,5 +1,7 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {UniqueMetadata} from "../../../src/metadata/UniqueMetadata";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {ForeignKeyMetadata} from "../../../src/metadata/ForeignKeyMetadata";
@ -21,6 +23,7 @@ describe("schema builder > create foreign key", () => {
const postMetadata = connection.getMetadata("post");
const columns = categoryMetadata.columns.filter(column => ["postText", "postTag"].indexOf(column.propertyName) !== -1);
const referencedColumns = postMetadata.columns.filter(column => ["text", "tag"].indexOf(column.propertyName) !== -1);
const fkMetadata = new ForeignKeyMetadata({
entityMetadata: categoryMetadata,
referencedEntityMetadata: postMetadata,
@ -30,6 +33,19 @@ describe("schema builder > create foreign key", () => {
});
categoryMetadata.foreignKeys.push(fkMetadata);
// CockroachDB requires unique constraint for foreign key referenced columns
if (connection.driver instanceof CockroachDriver) {
const uniqueConstraint = new UniqueMetadata({
entityMetadata: categoryMetadata,
columns: fkMetadata.columns,
args: {
name: connection.namingStrategy.relationConstraintName(categoryMetadata.tablePath, fkMetadata.columns.map(c => c.databaseName)),
target: categoryMetadata.target,
}
});
categoryMetadata.uniques.push(uniqueConstraint);
}
await connection.synchronize();
const queryRunner = connection.createQueryRunner();

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {closeTestingConnections, createTestingConnections} from "../../utils/test-utils";
import {expect} from "chai";
@ -17,6 +18,10 @@ describe("schema builder > drop column", () => {
it("should correctly drop column", () => Promise.all(connections.map(async connection => {
// TODO: https://github.com/cockroachdb/cockroach/issues/34710
if (connection.driver instanceof CockroachDriver)
return;
const studentMetadata = connection.getMetadata("student");
const removedColumns = studentMetadata.columns.filter(column => ["name", "faculty"].indexOf(column.propertyName) !== -1);
removedColumns.forEach(column => {

View File

@ -1,5 +1,6 @@
import "reflect-metadata";
import {Connection} from "../../../src/connection/Connection";
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
import {closeTestingConnections, createTestingConnections} from "../../utils/test-utils";
import {Category} from "./entity/Category";
import {Question} from "./entity/Question";
@ -19,6 +20,10 @@ describe("schema builder > update primary keys", () => {
it("should correctly update composite primary keys", () => Promise.all(connections.map(async connection => {
// CockroachDB does not support changing primary key constraint
if (connection.driver instanceof CockroachDriver)
return;
const metadata = connection.getMetadata(Category);
const nameColumn = metadata.findColumnWithPropertyName("name");
nameColumn!.isPrimary = true;
@ -38,6 +43,10 @@ describe("schema builder > update primary keys", () => {
if (connection.driver instanceof AbstractSqliteDriver)
return;
// CockroachDB does not support changing primary key constraint
if (connection.driver instanceof CockroachDriver)
return;
const metadata = connection.getMetadata(Question);
const nameColumn = metadata.findColumnWithPropertyName("name");
nameColumn!.isPrimary = true;