mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
working on tests;
bugfixes;
This commit is contained in:
parent
4032cdb431
commit
3bbd65cd00
@ -15,9 +15,7 @@ export class Post {
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@Column("int", {
|
||||
nullable: false
|
||||
})
|
||||
@Column({ nullable: false })
|
||||
likesCount: number;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,15 +171,15 @@ export class CockroachDriver implements Driver {
|
||||
createDateDefault: "now()",
|
||||
updateDate: "timestamptz",
|
||||
updateDateDefault: "now()",
|
||||
version: "int",
|
||||
treeLevel: "int",
|
||||
migrationId: "int",
|
||||
version: Number,
|
||||
treeLevel: Number,
|
||||
migrationId: Number,
|
||||
migrationName: "varchar",
|
||||
migrationTimestamp: "int8",
|
||||
cacheId: "int",
|
||||
cacheId: Number,
|
||||
cacheIdentifier: "varchar",
|
||||
cacheTime: "int8",
|
||||
cacheDuration: "int",
|
||||
cacheDuration: Number,
|
||||
cacheQuery: "string",
|
||||
cacheResult: "string",
|
||||
};
|
||||
@ -322,7 +322,7 @@ export class CockroachDriver implements Driver {
|
||||
return value;
|
||||
|
||||
// unique_rowid() generates bigint value and should not be converted to number
|
||||
if (columnMetadata.type === Number && !columnMetadata.isArray && !columnMetadata.isGenerated) {
|
||||
if ((columnMetadata.type === Number && !columnMetadata.isArray) || columnMetadata.generationStrategy === "increment") {
|
||||
value = parseInt(value);
|
||||
|
||||
} else if (columnMetadata.type === Boolean) {
|
||||
@ -411,7 +411,7 @@ export class CockroachDriver implements Driver {
|
||||
/**
|
||||
* Creates a database type from a given column metadata.
|
||||
*/
|
||||
normalizeType(column: { type?: ColumnType, length?: number | string, precision?: number|null, scale?: number, isArray?: boolean, isGenerated?: boolean, generationStrategy?: "increment"|"uuid" }): string {
|
||||
normalizeType(column: { type?: ColumnType, length?: number | string, precision?: number|null, scale?: number, isArray?: boolean, isGenerated?: boolean, generationStrategy?: "increment"|"uuid"|"rowid" }): string {
|
||||
if (column.type === Number || column.type === "integer" || column.type === "int4") {
|
||||
return "int";
|
||||
|
||||
@ -568,7 +568,7 @@ export class CockroachDriver implements Driver {
|
||||
return Object.keys(insertResult).reduce((map, key) => {
|
||||
const column = metadata.findColumnWithDatabaseName(key);
|
||||
if (column) {
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(insertResult[key]));
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(this.prepareHydratedValue(insertResult[key], column)));
|
||||
}
|
||||
return map;
|
||||
}, {} as ObjectLiteral);
|
||||
|
||||
@ -314,6 +314,13 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
const upQueries: string[] = [];
|
||||
const downQueries: string[] = [];
|
||||
|
||||
table.columns
|
||||
.filter(column => column.isGenerated && column.generationStrategy === "increment")
|
||||
.forEach(column => {
|
||||
upQueries.push(`CREATE SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
downQueries.push(`DROP SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
});
|
||||
|
||||
upQueries.push(this.createTableSql(table, createForeignKeys));
|
||||
downQueries.push(this.dropTableSql(table));
|
||||
|
||||
@ -369,6 +376,13 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
upQueries.push(this.dropTableSql(table));
|
||||
downQueries.push(this.createTableSql(table, createForeignKeys));
|
||||
|
||||
table.columns
|
||||
.filter(column => column.isGenerated && column.generationStrategy === "increment")
|
||||
.forEach(column => {
|
||||
upQueries.push(`DROP SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
downQueries.push(`CREATE SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
});
|
||||
|
||||
await this.executeQueries(upQueries, downQueries);
|
||||
}
|
||||
|
||||
@ -452,6 +466,10 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
const upQueries: string[] = [];
|
||||
const downQueries: string[] = [];
|
||||
|
||||
if (column.generationStrategy === "increment") {
|
||||
throw new Error(`Adding sequential generated columns into existing table is not supported`);
|
||||
}
|
||||
|
||||
upQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ADD ${this.buildCreateColumnSql(table, column)}`);
|
||||
downQueries.push(`ALTER TABLE ${this.escapeTableName(table)} DROP COLUMN "${column.name}"`);
|
||||
|
||||
@ -724,8 +742,13 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
|
||||
if (oldColumn.isGenerated !== newColumn.isGenerated && newColumn.generationStrategy !== "uuid") {
|
||||
if (newColumn.isGenerated) {
|
||||
upQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ALTER COLUMN "${newColumn.name}" SET DEFAULT unique_rowid()`);
|
||||
downQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ALTER COLUMN "${newColumn.name}" DROP DEFAULT`);
|
||||
if (newColumn.generationStrategy === "increment") {
|
||||
throw new Error(`Adding sequential generated columns into existing table is not supported`);
|
||||
|
||||
} else if (newColumn.generationStrategy === "rowid") {
|
||||
upQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ALTER COLUMN "${newColumn.name}" SET DEFAULT unique_rowid()`);
|
||||
downQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ALTER COLUMN "${newColumn.name}" DROP DEFAULT`);
|
||||
}
|
||||
|
||||
} else {
|
||||
upQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ALTER COLUMN "${newColumn.name}" DROP DEFAULT`);
|
||||
@ -823,6 +846,11 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
upQueries.push(`ALTER TABLE ${this.escapeTableName(table)} DROP COLUMN "${column.name}"`);
|
||||
downQueries.push(`ALTER TABLE ${this.escapeTableName(table)} ADD ${this.buildCreateColumnSql(table, column)}`);
|
||||
|
||||
if (column.generationStrategy === "increment") {
|
||||
upQueries.push(`DROP SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
downQueries.push(`CREATE SEQUENCE ${this.buildSequenceName(table, column)}`);
|
||||
}
|
||||
|
||||
await this.executeQueries(upQueries, downQueries);
|
||||
|
||||
clonedTable.removeColumn(column);
|
||||
@ -1084,7 +1112,7 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
// CockroachDB stores unique indices and UNIQUE constraints
|
||||
if (index.isUnique) {
|
||||
const unique = new TableUnique({
|
||||
name: this.connection.namingStrategy.uniqueConstraintName(table.name, index.columnNames),
|
||||
name: index.name,
|
||||
columnNames: index.columnNames
|
||||
});
|
||||
const up = this.createUniqueConstraintSql(table, unique);
|
||||
@ -1158,12 +1186,14 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
|
||||
await this.startTransaction();
|
||||
try {
|
||||
// ignore spatial_ref_sys; it's a special table supporting PostGIS
|
||||
// TODO generalize this as this.driver.ignoreTables
|
||||
const selectDropsQuery = `SELECT 'DROP TABLE IF EXISTS "' || schemaname || '"."' || tablename || '" CASCADE;' as "query" FROM "pg_tables" WHERE "schemaname" IN (${schemaNamesString}) AND tablename NOT IN ('spatial_ref_sys')`;
|
||||
const selectDropsQuery = `SELECT 'DROP TABLE IF EXISTS "' || table_schema || '"."' || table_name || '" CASCADE;' as "query" FROM "information_schema"."tables" WHERE "table_schema" IN (${schemaNamesString})`;
|
||||
const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
await Promise.all(dropQueries.map(q => this.query(q["query"])));
|
||||
|
||||
const selectSequenceDropsQuery = `SELECT 'DROP SEQUENCE "' || sequence_schema || '"."' || sequence_name || '";' as "query" FROM "information_schema"."sequences" WHERE "sequence_schema" IN (${schemaNamesString})`;
|
||||
const sequenceDropQueries: ObjectLiteral[] = await this.query(selectSequenceDropsQuery);
|
||||
await Promise.all(sequenceDropQueries.map(q => this.query(q["query"])));
|
||||
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
@ -1334,6 +1364,10 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
|
||||
if (dbColumn["column_default"] !== null && dbColumn["column_default"] !== undefined) {
|
||||
if (dbColumn["column_default"] === "unique_rowid()") {
|
||||
tableColumn.isGenerated = true;
|
||||
tableColumn.generationStrategy = "rowid";
|
||||
|
||||
} else if (dbColumn["column_default"].indexOf("nextval") !== -1) {
|
||||
tableColumn.isGenerated = true;
|
||||
tableColumn.generationStrategy = "increment";
|
||||
|
||||
@ -1624,24 +1658,9 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
/**
|
||||
* Builds sequence name from given table and column.
|
||||
*/
|
||||
protected buildSequenceName(table: Table, columnOrName: TableColumn|string, currentSchema?: string, disableEscape?: true, skipSchema?: boolean): string {
|
||||
protected buildSequenceName(table: Table, columnOrName: TableColumn|string, disableEscape?: true): string {
|
||||
const columnName = columnOrName instanceof TableColumn ? columnOrName.name : columnOrName;
|
||||
let schema: string|undefined = undefined;
|
||||
let tableName: string|undefined = undefined;
|
||||
|
||||
if (table.name.indexOf(".") === -1) {
|
||||
tableName = table.name;
|
||||
} else {
|
||||
schema = table.name.split(".")[0];
|
||||
tableName = table.name.split(".")[1];
|
||||
}
|
||||
|
||||
if (schema && schema !== currentSchema && !skipSchema) {
|
||||
return disableEscape ? `${schema}.${tableName}_${columnName}_seq` : `"${schema}"."${tableName}_${columnName}_seq"`;
|
||||
|
||||
} else {
|
||||
return disableEscape ? `${tableName}_${columnName}_seq` : `"${tableName}_${columnName}_seq"`;
|
||||
}
|
||||
return disableEscape ? `${table.name}_${columnName}_seq` : `"${table.name}_${columnName}_seq"`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1680,9 +1699,18 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
protected buildCreateColumnSql(table: Table, column: TableColumn) {
|
||||
let c = "\"" + column.name + "\"";
|
||||
|
||||
if (column.isGenerated && column.generationStrategy !== "uuid")
|
||||
c += " INT DEFAULT unique_rowid()";
|
||||
if (!column.isGenerated || column.type === "uuid")
|
||||
if (column.isGenerated) {
|
||||
if (column.generationStrategy === "increment") {
|
||||
c += ` INT DEFAULT nextval('${this.buildSequenceName(table, column)}')`;
|
||||
|
||||
} else if (column.generationStrategy === "rowid") {
|
||||
c += " INT DEFAULT unique_rowid()";
|
||||
|
||||
} else if (column.generationStrategy === "uuid") {
|
||||
c += " UUID DEFAULT gen_random_uuid()";
|
||||
}
|
||||
}
|
||||
if (!column.isGenerated)
|
||||
c += " " + this.connection.driver.createFullType(column);
|
||||
if (column.charset)
|
||||
c += " CHARACTER SET \"" + column.charset + "\"";
|
||||
@ -1690,10 +1718,8 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
|
||||
c += " COLLATE \"" + column.collation + "\"";
|
||||
if (!column.isNullable)
|
||||
c += " NOT NULL";
|
||||
if (column.default !== undefined && column.default !== null)
|
||||
if (!column.isGenerated && column.default !== undefined && column.default !== null)
|
||||
c += " DEFAULT " + column.default;
|
||||
if (column.isGenerated && column.generationStrategy === "uuid" && !column.default)
|
||||
c += " DEFAULT gen_random_uuid()";
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -556,7 +556,7 @@ export class OracleDriver implements Driver {
|
||||
return Object.keys(insertResult).reduce((map, key) => {
|
||||
const column = metadata.findColumnWithDatabaseName(key);
|
||||
if (column) {
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(insertResult[key]));
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(this.prepareHydratedValue(insertResult[key], column)));
|
||||
}
|
||||
return map;
|
||||
}, {} as ObjectLiteral);
|
||||
|
||||
@ -725,7 +725,7 @@ export class PostgresDriver implements Driver {
|
||||
return Object.keys(insertResult).reduce((map, key) => {
|
||||
const column = metadata.findColumnWithDatabaseName(key);
|
||||
if (column) {
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(insertResult[key]));
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(this.prepareHydratedValue(insertResult[key], column)));
|
||||
}
|
||||
return map;
|
||||
}, {} as ObjectLiteral);
|
||||
|
||||
@ -548,7 +548,7 @@ export class SqlServerDriver implements Driver {
|
||||
return Object.keys(insertResult).reduce((map, key) => {
|
||||
const column = metadata.findColumnWithDatabaseName(key);
|
||||
if (column) {
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(insertResult[key]));
|
||||
OrmUtils.mergeDeep(map, column.createValueMap(this.prepareHydratedValue(insertResult[key], column)));
|
||||
}
|
||||
return map;
|
||||
}, {} as ObjectLiteral);
|
||||
|
||||
@ -473,6 +473,7 @@ export class EntityMetadataBuilder {
|
||||
entityMetadata: entityMetadata,
|
||||
args: {
|
||||
target: args.target,
|
||||
name: args.name,
|
||||
columns: args.columns,
|
||||
}
|
||||
});
|
||||
|
||||
@ -103,7 +103,7 @@ export class ColumnMetadata {
|
||||
/**
|
||||
* Specifies generation strategy if this column will use auto increment.
|
||||
*/
|
||||
generationStrategy?: "uuid"|"increment";
|
||||
generationStrategy?: "uuid"|"increment"|"rowid";
|
||||
|
||||
/**
|
||||
* Column comment.
|
||||
@ -443,7 +443,7 @@ export class ColumnMetadata {
|
||||
}
|
||||
|
||||
// this is bugfix for #720 when increment number is bigint we need to make sure its a string
|
||||
if (this.generationStrategy === "increment" && this.type === "bigint")
|
||||
if ((this.generationStrategy === "increment" || this.generationStrategy === "rowid") && this.type === "bigint")
|
||||
value = String(value);
|
||||
|
||||
map[useDatabaseName ? this.databaseName : this.propertyName] = value;
|
||||
@ -454,7 +454,7 @@ export class ColumnMetadata {
|
||||
} else { // no embeds - no problems. Simply return column property name and its value of the entity
|
||||
|
||||
// this is bugfix for #720 when increment number is bigint we need to make sure its a string
|
||||
if (this.generationStrategy === "increment" && this.type === "bigint")
|
||||
if ((this.generationStrategy === "increment" || this.generationStrategy === "rowid") && this.type === "bigint")
|
||||
value = String(value);
|
||||
|
||||
return { [useDatabaseName ? this.databaseName : this.propertyName]: value };
|
||||
|
||||
@ -241,4 +241,4 @@ export class ManyToManySubjectBuilder {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,31 +475,6 @@ export abstract class QueryBuilder<Entity> {
|
||||
* schema name, otherwise returns escaped table name.
|
||||
*/
|
||||
protected getTableName(tablePath: string): string {
|
||||
// let tablePath = tableName;
|
||||
// const driver = this.connection.driver;
|
||||
// const schema = (driver.options as SqlServerConnectionOptions|PostgresConnectionOptions).schema;
|
||||
// const metadata = this.connection.hasMetadata(tableName) ? this.connection.getMetadata(tableName) : undefined;
|
||||
|
||||
/*if (driver instanceof SqlServerDriver || driver instanceof PostgresDriver || driver instanceof MysqlDriver) {
|
||||
if (metadata) {
|
||||
if (metadata.schema) {
|
||||
tablePath = `${metadata.schema}.${tableName}`;
|
||||
} else if (schema) {
|
||||
tablePath = `${schema}.${tableName}`;
|
||||
}
|
||||
|
||||
if (metadata.database && !(driver instanceof PostgresDriver)) {
|
||||
if (!schema && !metadata.schema && driver instanceof SqlServerDriver) {
|
||||
tablePath = `${metadata.database}..${tablePath}`;
|
||||
} else {
|
||||
tablePath = `${metadata.database}.${tablePath}`;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (schema) {
|
||||
tablePath = `${schema!}.${tableName}`;
|
||||
}
|
||||
}*/
|
||||
return tablePath.split(".")
|
||||
.map(i => {
|
||||
// this condition need because in SQL Server driver when custom database name was specified and schema name was not, we got `dbName..tableName` string, and doesn't need to escape middle empty string
|
||||
|
||||
@ -21,6 +21,10 @@ export class RelationCountLoader {
|
||||
|
||||
async load(rawEntities: any[]): Promise<RelationCountLoadResult[]> {
|
||||
|
||||
const onlyUnique = (value: any, index: number, self: any) => {
|
||||
return self.indexOf(value) === index;
|
||||
};
|
||||
|
||||
const promises = this.relationCountAttributes.map(async relationCountAttr => {
|
||||
|
||||
if (relationCountAttr.relation.isOneToMany) {
|
||||
@ -37,9 +41,10 @@ export class RelationCountLoader {
|
||||
const inverseSideTableAlias = relationCountAttr.alias || inverseSideTableName; // if condition (custom query builder factory) is set then relationIdAttr.alias defined
|
||||
const inverseSidePropertyName = inverseRelation.propertyName; // "category" from "post.category"
|
||||
|
||||
const referenceColumnValues = rawEntities
|
||||
let referenceColumnValues = rawEntities
|
||||
.map(rawEntity => rawEntity[relationCountAttr.parentAlias + "_" + referenceColumnName])
|
||||
.filter(value => !!value);
|
||||
referenceColumnValues = referenceColumnValues.filter(onlyUnique);
|
||||
|
||||
// ensure we won't perform redundant queries for joined data which was not found in selection
|
||||
// example: if post.category was not found in db then no need to execute query for category.imageIds
|
||||
@ -89,9 +94,10 @@ export class RelationCountLoader {
|
||||
secondJunctionColumn = relationCountAttr.relation.junctionEntityMetadata!.columns[0];
|
||||
}
|
||||
|
||||
const referenceColumnValues = rawEntities
|
||||
let referenceColumnValues = rawEntities
|
||||
.map(rawEntity => rawEntity[relationCountAttr.parentAlias + "_" + joinTableColumnName])
|
||||
.filter(value => value);
|
||||
.filter(value => !!value);
|
||||
referenceColumnValues = referenceColumnValues.filter(onlyUnique);
|
||||
|
||||
// ensure we won't perform redundant queries for joined data which was not found in selection
|
||||
// example: if post.category was not found in db then no need to execute query for category.imageIds
|
||||
|
||||
@ -36,11 +36,11 @@ export class RelationIdLoader {
|
||||
const results = rawEntities.map(rawEntity => {
|
||||
const result: ObjectLiteral = {};
|
||||
relationIdAttr.relation.joinColumns.forEach(joinColumn => {
|
||||
result[joinColumn.databaseName] = rawEntity[this.buildColumnAlias(relationIdAttr.parentAlias, joinColumn.databaseName)];
|
||||
result[joinColumn.databaseName] = this.connection.driver.prepareHydratedValue(rawEntity[this.buildColumnAlias(relationIdAttr.parentAlias, joinColumn.databaseName)], joinColumn.referencedColumn!);
|
||||
});
|
||||
|
||||
relationIdAttr.relation.entityMetadata.primaryColumns.forEach(primaryColumn => {
|
||||
result[primaryColumn.databaseName] = rawEntity[this.buildColumnAlias(relationIdAttr.parentAlias, primaryColumn.databaseName)];
|
||||
result[primaryColumn.databaseName] = this.connection.driver.prepareHydratedValue(rawEntity[this.buildColumnAlias(relationIdAttr.parentAlias, primaryColumn.databaseName)], primaryColumn);
|
||||
});
|
||||
return result;
|
||||
});
|
||||
@ -96,9 +96,19 @@ export class RelationIdLoader {
|
||||
if (relationIdAttr.queryBuilderFactory)
|
||||
relationIdAttr.queryBuilderFactory(qb);
|
||||
|
||||
const results = await qb.getRawMany();
|
||||
results.forEach(result => {
|
||||
joinColumns.forEach(column => {
|
||||
result[column.databaseName] = this.connection.driver.prepareHydratedValue(result[column.databaseName], column.referencedColumn!);
|
||||
});
|
||||
relation.inverseRelation!.entityMetadata.primaryColumns.forEach(column => {
|
||||
result[column.databaseName] = this.connection.driver.prepareHydratedValue(result[column.databaseName], column);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
relationIdAttribute: relationIdAttr,
|
||||
results: await qb.getRawMany()
|
||||
results
|
||||
};
|
||||
|
||||
} else {
|
||||
@ -166,9 +176,16 @@ export class RelationIdLoader {
|
||||
if (relationIdAttr.queryBuilderFactory)
|
||||
relationIdAttr.queryBuilderFactory(qb);
|
||||
|
||||
const results = await qb.getRawMany();
|
||||
results.forEach(result => {
|
||||
[...joinColumns, ...inverseJoinColumns].forEach(column => {
|
||||
result[column.databaseName] = this.connection.driver.prepareHydratedValue(result[column.databaseName], column.referencedColumn!);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
relationIdAttribute: relationIdAttr,
|
||||
results: await qb.getRawMany()
|
||||
results
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@ -332,9 +332,9 @@ export class RawSqlResultsToEntityTransformer {
|
||||
return columns.reduce((valueMap, column) => {
|
||||
rawSqlResults.forEach(rawSqlResult => {
|
||||
if (relation.isManyToOne || relation.isOneToOneOwner) {
|
||||
valueMap[column.databaseName] = rawSqlResult[this.buildColumnAlias(parentAlias, column.databaseName)];
|
||||
valueMap[column.databaseName] = this.driver.prepareHydratedValue(rawSqlResult[this.buildColumnAlias(parentAlias, column.databaseName)], column);
|
||||
} else {
|
||||
valueMap[column.databaseName] = rawSqlResult[this.buildColumnAlias(parentAlias, column.referencedColumn!.databaseName)];
|
||||
valueMap[column.databaseName] = this.driver.prepareHydratedValue(rawSqlResult[this.buildColumnAlias(parentAlias, column.referencedColumn!.databaseName)], column);
|
||||
}
|
||||
});
|
||||
return valueMap;
|
||||
@ -369,4 +369,4 @@ export class RawSqlResultsToEntityTransformer {
|
||||
virtualColumns.forEach(virtualColumn => delete entity[virtualColumn]);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,9 +163,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
|
||||
// find foreign keys that exist in the schemas but does not exist in the entity metadata
|
||||
const tableForeignKeysToDrop = table.foreignKeys.filter(tableForeignKey => {
|
||||
const metadataFK = metadata.foreignKeys.find(metadataForeignKey => metadataForeignKey.name === tableForeignKey.name);
|
||||
return !metadataFK
|
||||
|| metadataFK.onDelete && metadataFK.onDelete !== tableForeignKey.onDelete
|
||||
|| metadataFK.onUpdate && metadataFK.onUpdate !== tableForeignKey.onUpdate; // TODO: bug, fix later (messer)
|
||||
return !metadataFK || metadataFK.onDelete !== tableForeignKey.onDelete || metadataFK.onUpdate !== tableForeignKey.onUpdate;
|
||||
});
|
||||
if (tableForeignKeysToDrop.length === 0)
|
||||
return;
|
||||
|
||||
@ -41,7 +41,7 @@ export interface TableColumnOptions {
|
||||
/**
|
||||
* Specifies generation strategy if this column will use auto increment.
|
||||
*/
|
||||
generationStrategy?: "uuid"|"increment";
|
||||
generationStrategy?: "uuid"|"increment"|"rowid";
|
||||
|
||||
/**
|
||||
* Indicates if column is a primary key.
|
||||
|
||||
@ -41,8 +41,9 @@ export class TableColumn {
|
||||
|
||||
/**
|
||||
* Specifies generation strategy if this column will use auto increment.
|
||||
* `rowid` option supported only in CockroachDB.
|
||||
*/
|
||||
generationStrategy?: "uuid"|"increment";
|
||||
generationStrategy?: "uuid"|"increment"|"rowid";
|
||||
|
||||
/**
|
||||
* Indicates if column is a primary key.
|
||||
@ -203,4 +204,4 @@ export class TableColumn {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "reflect-metadata";
|
||||
import {CockroachDriver} from "../../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
|
||||
import {Connection} from "../../../../src/connection/Connection";
|
||||
import {expect} from "chai";
|
||||
@ -12,7 +13,6 @@ describe("database schema > indices > reading index from entity and updating dat
|
||||
let connections: Connection[];
|
||||
before(async () => connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
enabledDrivers: ["mysql"]
|
||||
}));
|
||||
beforeEach(() => reloadTestingDatabases(connections));
|
||||
after(() => closeTestingConnections(connections));
|
||||
@ -43,11 +43,19 @@ describe("database schema > indices > reading index from entity and updating dat
|
||||
const table = await queryRunner.getTable("person");
|
||||
await queryRunner.release();
|
||||
|
||||
expect(table!.indices.length).to.be.equal(1);
|
||||
expect(table!.indices[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.indices[0].isUnique).to.be.true;
|
||||
expect(table!.indices[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.indices[0].columnNames).to.include.members(["firstname", "lastname"]);
|
||||
// CockroachDB stores unique indices as UNIQUE constraints
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
expect(table!.uniques.length).to.be.equal(1);
|
||||
expect(table!.uniques[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.uniques[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.uniques[0].columnNames).to.include.members(["firstname", "firstname"]);
|
||||
} else {
|
||||
expect(table!.indices.length).to.be.equal(1);
|
||||
expect(table!.indices[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.indices[0].isUnique).to.be.true;
|
||||
expect(table!.indices[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.indices[0].columnNames).to.include.members(["firstname", "firstname"]);
|
||||
}
|
||||
|
||||
})));
|
||||
|
||||
|
||||
@ -251,6 +251,8 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
|
||||
.addOrderBy("post.id, categories.id")
|
||||
.getMany();
|
||||
|
||||
// console.log(loadedPosts);
|
||||
|
||||
expect(loadedPosts![0].categoryCount).to.be.equal(3);
|
||||
expect(loadedPosts![0].categories[0].postCount).to.be.equal(2);
|
||||
expect(loadedPosts![0].categories[1].postCount).to.be.equal(1);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../../src/decorator/columns/Column";
|
||||
import {OneToOne} from "../../../../../../src/decorator/relations/OneToOne";
|
||||
import {JoinColumn} from "../../../../../../src/decorator/relations/JoinColumn";
|
||||
@ -9,12 +9,9 @@ import {RelationId} from "../../../../../../src/decorator/relations/RelationId";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
code: number;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
|
||||
@ -12,14 +12,13 @@ describe("embedded > embedded-many-to-many-case1", () => {
|
||||
let connections: Connection[];
|
||||
before(async () => connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
enabledDrivers: ["cockroachdb"]
|
||||
}));
|
||||
beforeEach(() => reloadTestingDatabases(connections));
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
describe("owner side", () => {
|
||||
|
||||
it.only("should insert, load, update and remove entities with embeddeds when embedded entity having ManyToMany relation", () => Promise.all(connections.map(async connection => {
|
||||
it("should insert, load, update and remove entities with embeddeds when embedded entity having ManyToMany relation", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const user1 = new User();
|
||||
user1.id = 1;
|
||||
|
||||
@ -36,6 +36,7 @@ describe("entity-model", () => {
|
||||
Category.useConnection(connection);
|
||||
|
||||
const category = Category.create();
|
||||
category.id = 1;
|
||||
category.name = "Persistence";
|
||||
await category.save();
|
||||
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import {PrimaryColumn} from "../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../src/decorator/entity/Entity";
|
||||
import {BaseEntity} from "../../../../src/repository/BaseEntity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class Category extends BaseEntity {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "reflect-metadata";
|
||||
import {CockroachDriver} from "../../../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../../utils/test-utils";
|
||||
import {Connection} from "../../../../../src/connection/Connection";
|
||||
import {EntityMetadata} from "../../../../../src/metadata/EntityMetadata";
|
||||
@ -41,11 +42,19 @@ describe("entity-schema > indices > basic", () => {
|
||||
const table = await queryRunner.getTable("person");
|
||||
await queryRunner.release();
|
||||
|
||||
expect(table!.indices.length).to.be.equal(1);
|
||||
expect(table!.indices[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.indices[0].isUnique).to.be.true;
|
||||
expect(table!.indices[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.indices[0].columnNames).to.include.members(["FirstName", "LastName"]);
|
||||
// CockroachDB stores unique indices as UNIQUE constraints
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
expect(table!.uniques.length).to.be.equal(1);
|
||||
expect(table!.uniques[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.uniques[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.uniques[0].columnNames).to.include.members(["FirstName", "LastName"]);
|
||||
} else {
|
||||
expect(table!.indices.length).to.be.equal(1);
|
||||
expect(table!.indices[0].name).to.be.equal("IDX_TEST");
|
||||
expect(table!.indices[0].isUnique).to.be.true;
|
||||
expect(table!.indices[0].columnNames.length).to.be.equal(2);
|
||||
expect(table!.indices[0].columnNames).to.include.members(["FirstName", "LastName"]);
|
||||
}
|
||||
|
||||
})));
|
||||
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
constructor(name: string) {
|
||||
constructor(id: number, name: string) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
constructor(title: string) {
|
||||
constructor(id: number, title: string) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
constructor(name: string) {
|
||||
constructor(id: number, name: string) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,11 +17,11 @@ describe("persistence > basic functionality", function() {
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("should save an entity", () => Promise.all(connections.map(async connection => {
|
||||
await connection.manager.save(new Post("Hello Post"));
|
||||
await connection.manager.save(new Post(1, "Hello Post"));
|
||||
})));
|
||||
|
||||
it("should remove an entity", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
await connection.manager.remove(post);
|
||||
})));
|
||||
@ -41,16 +41,16 @@ describe("persistence > basic functionality", function() {
|
||||
it("should throw an exception if object literal is given instead of constructed entity because it cannot determine what to save", () => Promise.all(connections.map(async connection => {
|
||||
await connection.manager.save({}).should.be.rejectedWith(`Cannot save, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.save([{}, {}]).should.be.rejectedWith(`Cannot save, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.save([new Post("Hello Post"), {}]).should.be.rejectedWith(`Cannot save, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.save([new Post(1, "Hello Post"), {}]).should.be.rejectedWith(`Cannot save, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.remove({}).should.be.rejectedWith(`Cannot remove, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.remove([{}, {}]).should.be.rejectedWith(`Cannot remove, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.remove([new Post("Hello Post"), {}]).should.be.rejectedWith(`Cannot remove, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
await connection.manager.remove([new Post(1, "Hello Post"), {}]).should.be.rejectedWith(`Cannot remove, given value must be instance of entity class, instead object literal is given. Or you must specify an entity target to method call.`);
|
||||
})));
|
||||
|
||||
it("should be able to save and remove entities of different types", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const category = new Category("Hello Category");
|
||||
const user = new User("Hello User");
|
||||
const post = new Post(1, "Hello Post");
|
||||
const category = new Category(1, "Hello Category");
|
||||
const user = new User(1, "Hello User");
|
||||
|
||||
await connection.manager.save([post, category, user]);
|
||||
await connection.manager.findOne(Post, 1).should.eventually.eql({ id: 1, title: "Hello Post" });
|
||||
|
||||
@ -17,14 +17,11 @@ describe("persistence > cascades > example 1", () => {
|
||||
it("should insert everything by cascades properly", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const photo = new Photo();
|
||||
photo.id = 1;
|
||||
|
||||
const profile = new Profile();
|
||||
profile.id = 1;
|
||||
profile.photo = photo;
|
||||
|
||||
const user = new User();
|
||||
user.id = 1;
|
||||
user.profile = profile;
|
||||
|
||||
await connection.manager.save(user);
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
|
||||
@Entity()
|
||||
export class Photo {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {User} from "./User";
|
||||
import {Photo} from "./Photo";
|
||||
import {OneToOne} from "../../../../../../src/decorator/relations/OneToOne";
|
||||
@ -8,7 +8,7 @@ import {JoinColumn} from "../../../../../../src/decorator/relations/JoinColumn";
|
||||
@Entity()
|
||||
export class Profile {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@OneToOne(type => User, user => user.profile, {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Profile} from "./Profile";
|
||||
import {OneToOne} from "../../../../../../src/decorator/relations/OneToOne";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@OneToOne(type => Profile, profile => profile.user, { cascade: ["insert"] })
|
||||
|
||||
@ -18,23 +18,17 @@ describe("persistence > cascades > example 2", () => {
|
||||
it("should insert everything by cascades properly", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const photo = new Photo();
|
||||
photo.id = 1;
|
||||
|
||||
const user = new User();
|
||||
user.id = 1;
|
||||
|
||||
const answer1 = new Answer();
|
||||
answer1.id = 1;
|
||||
answer1.photo = photo;
|
||||
answer1.user = user;
|
||||
|
||||
const answer2 = new Answer();
|
||||
answer2.id = 2;
|
||||
answer2.photo = photo;
|
||||
answer2.user = user;
|
||||
|
||||
const question = new Question();
|
||||
question.id = 1;
|
||||
question.answers = [answer1, answer2];
|
||||
user.question = question;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {ManyToOne} from "../../../../../../src/decorator/relations/ManyToOne";
|
||||
import {Photo} from "./Photo";
|
||||
import {User} from "./User";
|
||||
@ -8,7 +8,7 @@ import {Question} from "./Question";
|
||||
@Entity()
|
||||
export class Answer {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@ManyToOne(type => Question, question => question.answers, {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
|
||||
@Entity()
|
||||
export class Photo {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Answer} from "./Answer";
|
||||
import {OneToMany} from "../../../../../../src/decorator/relations/OneToMany";
|
||||
|
||||
@Entity()
|
||||
export class Question {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@OneToMany(type => Answer, answer => answer.question, { cascade: ["insert"] })
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import {PrimaryColumn} from "../../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Question} from "./Question";
|
||||
import {ManyToOne} from "../../../../../../src/decorator/relations/ManyToOne";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryColumn()
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@ManyToOne(type => Question, {
|
||||
|
||||
@ -8,7 +8,7 @@ import {Generated} from "../../../../../src/decorator/Generated";
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryColumn("int", {name: "theId"})
|
||||
@PrimaryColumn({name: "theId"})
|
||||
@Generated()
|
||||
id: number;
|
||||
|
||||
@ -20,4 +20,4 @@ export class Category {
|
||||
})
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import {Generated} from "../../../../../src/decorator/Generated";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn("int", {name: "theId"})
|
||||
@PrimaryColumn({name: "theId"})
|
||||
@Generated()
|
||||
id: number;
|
||||
|
||||
@ -20,4 +20,4 @@ export class Post {
|
||||
})
|
||||
category: Category;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {PostIncrement} from "./entity/PostIncrement";
|
||||
import {PostUuid} from "./entity/PostUuid";
|
||||
@ -21,7 +22,9 @@ describe("persistence > entity updation", () => {
|
||||
const post = new PostIncrement();
|
||||
post.text = "Hello Post";
|
||||
await connection.manager.save(post);
|
||||
post.id.should.be.equal(1);
|
||||
// CockroachDB does not use incremental ids
|
||||
if (!(connection.driver instanceof CockroachDriver))
|
||||
post.id.should.be.equal(1);
|
||||
})));
|
||||
|
||||
it("should update generated uuid after saving", () => Promise.all(connections.map(async connection => {
|
||||
@ -36,7 +39,6 @@ describe("persistence > entity updation", () => {
|
||||
const post = new PostDefaultValues();
|
||||
post.title = "Post #1";
|
||||
await connection.manager.save(post);
|
||||
post.id.should.be.equal(1);
|
||||
post.title.should.be.equal("Post #1");
|
||||
post.text.should.be.equal("hello post");
|
||||
post.isActive.should.be.equal(true);
|
||||
@ -49,7 +51,6 @@ describe("persistence > entity updation", () => {
|
||||
const post = new PostSpecialColumns();
|
||||
post.title = "Post #1";
|
||||
await connection.manager.save(post);
|
||||
post.id.should.be.equal(1);
|
||||
post.title.should.be.equal("Post #1");
|
||||
post.createDate.should.be.instanceof(Date);
|
||||
post.updateDate.should.be.instanceof(Date);
|
||||
|
||||
@ -48,7 +48,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser = await userRepository.findOne(1, {
|
||||
const loadedUser = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -93,7 +93,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser1 = await userRepository.findOne(1, {
|
||||
const loadedUser1 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -111,7 +111,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser2 = await userRepository.findOne(1, {
|
||||
const loadedUser2 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -157,7 +157,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser1 = await userRepository.findOne(1, {
|
||||
const loadedUser1 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -175,7 +175,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser2 = await userRepository.findOne(1, {
|
||||
const loadedUser2 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -220,7 +220,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser1 = await userRepository.findOne(1, {
|
||||
const loadedUser1 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
@ -238,7 +238,7 @@ describe("persistence > many-to-many", function() {
|
||||
await userRepository.save(newUser);
|
||||
|
||||
// load a post
|
||||
const loadedUser2 = await userRepository.findOne(1, {
|
||||
const loadedUser2 = await userRepository.findOne(newUser.id, {
|
||||
join: {
|
||||
alias: "user",
|
||||
leftJoinAndSelect: { post: "user.post", categories: "post.categories" }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {ManyToOne} from "../../../../../src/decorator/relations/ManyToOne";
|
||||
import {Post} from "./Post";
|
||||
@ -7,7 +7,7 @@ import {Post} from "./Post";
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -19,10 +19,11 @@ export class Category {
|
||||
})
|
||||
post?: Post|null|number;
|
||||
|
||||
constructor(name: string, post?: Post) {
|
||||
constructor(id: number, name: string, post?: Post) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
if (post)
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {Category} from "./Category";
|
||||
import {OneToMany} from "../../../../../src/decorator/relations/OneToMany";
|
||||
@ -7,7 +7,7 @@ import {OneToMany} from "../../../../../src/decorator/relations/OneToMany";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -16,8 +16,9 @@ export class Post {
|
||||
@OneToMany(type => Category, category => category.post)
|
||||
categories: Category[];
|
||||
|
||||
constructor(title: string) {
|
||||
constructor(id: number, title: string) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,10 +17,10 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("should save a category with a post attached", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -30,8 +30,8 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should save a category and a new post by cascades", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const category = new Category("Hello Category");
|
||||
const post = new Post(1, "Hello Post");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -41,11 +41,11 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should update exist post by cascades when category is saved", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
post.title = "Updated post";
|
||||
await connection.manager.save(category);
|
||||
@ -67,11 +67,11 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should NOT remove exist post by cascades when category is saved without a post (post is set to undefined)", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -94,11 +94,11 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should unset exist post when its set to null", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -116,11 +116,11 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should set category's post to NULL when post is removed from the database (database ON DELETE)", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -140,14 +140,14 @@ describe("persistence > many-to-one bi-directional relation", function() {
|
||||
|
||||
it("should work when relation id is directly set into relation (without related object)", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const post1 = new Post("Hello Post #1");
|
||||
const post1 = new Post(1, "Hello Post #1");
|
||||
await connection.manager.save(post1);
|
||||
|
||||
const post2 = new Post("Hello Post #2");
|
||||
const post2 = new Post(2, "Hello Post #2");
|
||||
await connection.manager.save(post2);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = 1;
|
||||
await connection.manager.save(category);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {ManyToOne} from "../../../../../src/decorator/relations/ManyToOne";
|
||||
import {Post} from "./Post";
|
||||
@ -7,7 +7,7 @@ import {Post} from "./Post";
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -19,10 +19,11 @@ export class Category {
|
||||
})
|
||||
post?: Post|null|number;
|
||||
|
||||
constructor(name: string, post?: Post) {
|
||||
constructor(id: number, name: string, post?: Post) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
if (post)
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
constructor(title: string) {
|
||||
constructor(id: number, title: string) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,10 +17,10 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
after(() => closeTestingConnections(connections));
|
||||
|
||||
it("should save a category with a post attached", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -30,8 +30,8 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should save a category and a new post by cascades", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const category = new Category("Hello Category");
|
||||
const post = new Post(1, "Hello Post");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -41,11 +41,11 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should update exist post by cascades when category is saved", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
post.title = "Updated post";
|
||||
await connection.manager.save(category);
|
||||
@ -67,11 +67,11 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should NOT remove exist post by cascades when category is saved without a post (post is set to undefined)", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -94,11 +94,11 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should unset exist post when its set to null", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -116,11 +116,11 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
})));
|
||||
|
||||
it("should set category's post to NULL when post is removed from the database (database ON DELETE)", () => Promise.all(connections.map(async connection => {
|
||||
const post = new Post("Hello Post");
|
||||
const post = new Post(1, "Hello Post");
|
||||
await connection.manager.save(post);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = post;
|
||||
await connection.manager.save(category);
|
||||
|
||||
@ -140,14 +140,14 @@ describe("persistence > many-to-one uni-directional relation", function() {
|
||||
|
||||
it("should work when relation id is directly set into relation (without related object)", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const post1 = new Post("Hello Post #1");
|
||||
const post1 = new Post(1, "Hello Post #1");
|
||||
await connection.manager.save(post1);
|
||||
|
||||
const post2 = new Post("Hello Post #2");
|
||||
const post2 = new Post(2, "Hello Post #2");
|
||||
await connection.manager.save(post2);
|
||||
|
||||
// update exist post from newly created category
|
||||
const category = new Category("Hello Category");
|
||||
const category = new Category(1, "Hello Category");
|
||||
category.post = 1;
|
||||
await connection.manager.save(category);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import {OneToMany} from "../../../../../src/decorator/relations/OneToMany";
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
categoryId: number;
|
||||
|
||||
@Column()
|
||||
@ -17,4 +17,4 @@ export class Category {
|
||||
@OneToMany(type => Post, post => post.category)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,10 +7,10 @@ import {Category} from "./Category";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
firstId: number;
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
secondId: number;
|
||||
|
||||
@Column()
|
||||
@ -19,4 +19,4 @@ export class Post {
|
||||
@ManyToOne(type => Category, category => category.posts)
|
||||
category: Category;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ describe("persistence > multi primary keys", () => {
|
||||
|
||||
describe("insert", function () {
|
||||
|
||||
it("should insert entity when when there are multi column primary keys", () => Promise.all(connections.map(async connection => {
|
||||
it("should insert entity when there are multi column primary keys", () => Promise.all(connections.map(async connection => {
|
||||
const post1 = new Post();
|
||||
post1.title = "Hello Post #1";
|
||||
post1.firstId = 1;
|
||||
|
||||
@ -7,10 +7,10 @@ import {Category} from "./Category";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
firstId: number;
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
secondId: number;
|
||||
|
||||
@Column()
|
||||
@ -19,4 +19,4 @@ export class Post {
|
||||
@ManyToOne(type => Category, category => category.posts)
|
||||
category: Category;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ describe("persistence > multi primary keys", () => {
|
||||
|
||||
describe("insert", function () {
|
||||
|
||||
it("should insert entity when when there are multi column primary keys", () => Promise.all(connections.map(async connection => {
|
||||
it("should insert entity when there are multi column primary keys", () => Promise.all(connections.map(async connection => {
|
||||
const post1 = new Post();
|
||||
post1.title = "Hello Post #1";
|
||||
post1.firstId = 1;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ type: String, default: "hello default value", nullable: true })
|
||||
title?: string|null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ describe("persistence > null and default behaviour", () => {
|
||||
|
||||
// create category
|
||||
const post = new Post();
|
||||
post.id = 1;
|
||||
post.title = "Category saved!";
|
||||
await connection.manager.save(post);
|
||||
|
||||
@ -34,6 +35,7 @@ describe("persistence > null and default behaviour", () => {
|
||||
|
||||
// create category
|
||||
const post = new Post();
|
||||
post.id = 1;
|
||||
await connection.manager.save(post);
|
||||
|
||||
const loadedPost = await connection.manager.findOne(Post, 1);
|
||||
@ -49,6 +51,7 @@ describe("persistence > null and default behaviour", () => {
|
||||
|
||||
// create category
|
||||
const post = new Post();
|
||||
post.id = 1;
|
||||
post.title = null;
|
||||
await connection.manager.save(post);
|
||||
|
||||
@ -65,6 +68,7 @@ describe("persistence > null and default behaviour", () => {
|
||||
|
||||
// create category
|
||||
const post = new Post();
|
||||
post.id = 1;
|
||||
post.title = "Category saved!";
|
||||
await connection.manager.save(post);
|
||||
|
||||
@ -82,8 +86,8 @@ describe("persistence > null and default behaviour", () => {
|
||||
|
||||
it("should update to null when post.title is null", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
// create category
|
||||
const post = new Post();
|
||||
post.id = 1;
|
||||
post.title = "Category saved!";
|
||||
await connection.manager.save(post);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Post} from "./Post";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {ManyToMany} from "../../../../../src/decorator/relations/ManyToMany";
|
||||
@ -7,7 +7,7 @@ import {ManyToMany} from "../../../../../src/decorator/relations/ManyToMany";
|
||||
@Entity()
|
||||
export class Category {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -19,4 +19,4 @@ export class Category {
|
||||
@ManyToMany(type => Post, post => post.categories)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Category} from "./Category";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {ManyToMany} from "../../../../../src/decorator/relations/ManyToMany";
|
||||
import {JoinTable} from "../../../../../src/decorator/relations/JoinTable";
|
||||
@ -9,7 +9,7 @@ import {Counters} from "./Counters";
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -27,4 +27,4 @@ export class Post {
|
||||
@JoinTable()
|
||||
categories: Category[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,12 +30,14 @@ describe("persistence > partial persist", () => {
|
||||
|
||||
// save a new category
|
||||
const newCategory = new Category();
|
||||
newCategory.id = 1;
|
||||
newCategory.name = "Animals";
|
||||
newCategory.position = 999;
|
||||
await categoryRepository.save(newCategory);
|
||||
|
||||
// save a new post
|
||||
const newPost = new Post();
|
||||
newPost.id = 1;
|
||||
newPost.title = "All about animals";
|
||||
newPost.description = "Description of the post about animals";
|
||||
newPost.categories = [newCategory];
|
||||
|
||||
@ -308,4 +308,4 @@ describe("query builder > cache", () => {
|
||||
|
||||
})));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {Counters} from "./Counters";
|
||||
|
||||
@Entity()
|
||||
export class Photo {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -15,4 +15,4 @@ export class Photo {
|
||||
@Column(type => Counters)
|
||||
counters: Counters;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
|
||||
import {Column} from "../../../../../src/decorator/columns/Column";
|
||||
import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn";
|
||||
import {Entity} from "../../../../../src/decorator/entity/Entity";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ describe("query builder > delete", () => {
|
||||
it("should perform deletion correctly", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
const user1 = new User();
|
||||
user1.id = 1;
|
||||
user1.name = "Alex Messer";
|
||||
await connection.manager.save(user1);
|
||||
|
||||
@ -30,6 +31,7 @@ describe("query builder > delete", () => {
|
||||
expect(loadedUser1).to.not.exist;
|
||||
|
||||
const user2 = new User();
|
||||
user1.id = 2;
|
||||
user2.name = "Alex Messer";
|
||||
await connection.manager.save(user2);
|
||||
|
||||
@ -47,8 +49,9 @@ describe("query builder > delete", () => {
|
||||
it("should be able to delete entities by embed criteria", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
// save few photos
|
||||
await connection.manager.save(Photo, { url: "1.jpg" });
|
||||
await connection.manager.save(Photo, { id: 1, url: "1.jpg" });
|
||||
await connection.manager.save(Photo, {
|
||||
id: 2,
|
||||
url: "2.jpg",
|
||||
counters: {
|
||||
likes: 2,
|
||||
@ -56,7 +59,7 @@ describe("query builder > delete", () => {
|
||||
comments: 1,
|
||||
}
|
||||
});
|
||||
await connection.manager.save(Photo, { url: "3.jpg" });
|
||||
await connection.manager.save(Photo, { id: 3, url: "3.jpg" });
|
||||
|
||||
// make sure photo with likes = 2 exist
|
||||
const loadedPhoto1 = await connection.getRepository(Photo).findOne({ counters: { likes: 2 } });
|
||||
@ -92,4 +95,4 @@ describe("query builder > delete", () => {
|
||||
expect(loadedPhoto4).to.exist;
|
||||
})));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import "reflect-metadata";
|
||||
import {expect} from "chai";
|
||||
import {CockroachDriver} from "../../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
|
||||
import {Connection} from "../../../../src/connection/Connection";
|
||||
import {Tag} from "./entity/Tag";
|
||||
@ -177,7 +178,12 @@ describe("query builder > joins", () => {
|
||||
.where("post.id = :id", { id: post.id })
|
||||
.getRawOne();
|
||||
|
||||
expect(loadedRawPost!["categories_id"]).to.be.equal(1);
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
expect(loadedRawPost!["categories_id"]).to.be.equal("1");
|
||||
|
||||
} else {
|
||||
expect(loadedRawPost!["categories_id"]).to.be.equal(1);
|
||||
}
|
||||
|
||||
})));
|
||||
|
||||
@ -823,4 +829,4 @@ describe("query builder > joins", () => {
|
||||
})));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "reflect-metadata";
|
||||
import {CockroachDriver} from "../../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
|
||||
import {Connection} from "../../../../src/connection/Connection";
|
||||
import {PostWithVersion} from "./entity/PostWithVersion";
|
||||
@ -57,7 +58,7 @@ describe("query builder > locking", () => {
|
||||
})));
|
||||
|
||||
it("should not throw error if pessimistic lock used with transaction", () => Promise.all(connections.map(async connection => {
|
||||
if (connection.driver instanceof AbstractSqliteDriver)
|
||||
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
|
||||
return;
|
||||
|
||||
return connection.manager.transaction(entityManager => {
|
||||
@ -76,7 +77,7 @@ describe("query builder > locking", () => {
|
||||
})));
|
||||
|
||||
it("should attach pessimistic read lock statement on query if locking enabled", () => Promise.all(connections.map(async connection => {
|
||||
if (connection.driver instanceof AbstractSqliteDriver)
|
||||
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
|
||||
return;
|
||||
|
||||
const sql = connection.createQueryBuilder(PostWithVersion, "post")
|
||||
@ -111,7 +112,7 @@ describe("query builder > locking", () => {
|
||||
})));
|
||||
|
||||
it("should attach pessimistic write lock statement on query if locking enabled", () => Promise.all(connections.map(async connection => {
|
||||
if (connection.driver instanceof AbstractSqliteDriver)
|
||||
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
|
||||
return;
|
||||
|
||||
const sql = connection.createQueryBuilder(PostWithVersion, "post")
|
||||
@ -260,7 +261,7 @@ describe("query builder > locking", () => {
|
||||
})));
|
||||
|
||||
it("should throw error if pessimistic locking not supported by given driver", () => Promise.all(connections.map(async connection => {
|
||||
if (connection.driver instanceof AbstractSqliteDriver)
|
||||
if (connection.driver instanceof AbstractSqliteDriver || connection.driver instanceof CockroachDriver)
|
||||
return connection.manager.transaction(entityManager => {
|
||||
return Promise.all([
|
||||
entityManager.createQueryBuilder(PostWithVersion, "post")
|
||||
|
||||
@ -109,4 +109,4 @@ describe("query builder > relation-id > many-to-one > embedded", () => {
|
||||
|
||||
})));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "reflect-metadata";
|
||||
import {CockroachDriver} from "../../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
|
||||
import {Connection} from "../../../../src/connection/Connection";
|
||||
import {User} from "./entity/User";
|
||||
@ -264,11 +265,21 @@ describe("query builder > sub-query", () => {
|
||||
.orderBy("post.id")
|
||||
.getRawMany();
|
||||
|
||||
posts.should.be.eql([
|
||||
{ id: 1, name: "Alex Messer" },
|
||||
{ id: 2, name: "Alex Messer" },
|
||||
{ id: 3, name: "Alex Messer" },
|
||||
]);
|
||||
// CockroachDB returns numeric data types as string
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
posts.should.be.eql([
|
||||
{ id: "1", name: "Alex Messer" },
|
||||
{ id: "2", name: "Alex Messer" },
|
||||
{ id: "3", name: "Alex Messer" },
|
||||
]);
|
||||
|
||||
} else {
|
||||
posts.should.be.eql([
|
||||
{ id: 1, name: "Alex Messer" },
|
||||
{ id: 2, name: "Alex Messer" },
|
||||
{ id: 3, name: "Alex Messer" },
|
||||
]);
|
||||
}
|
||||
})));
|
||||
|
||||
it("should execute sub query in selects (using provided sub query builder)", () => Promise.all(connections.map(async connection => {
|
||||
@ -288,11 +299,21 @@ describe("query builder > sub-query", () => {
|
||||
.orderBy("post.id")
|
||||
.getRawMany();
|
||||
|
||||
posts.should.be.eql([
|
||||
{ id: 1, name: "Alex Messer" },
|
||||
{ id: 2, name: "Alex Messer" },
|
||||
{ id: 3, name: "Alex Messer" },
|
||||
]);
|
||||
// CockroachDB returns numeric data types as string
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
posts.should.be.eql([
|
||||
{ id: "1", name: "Alex Messer" },
|
||||
{ id: "2", name: "Alex Messer" },
|
||||
{ id: "3", name: "Alex Messer" },
|
||||
]);
|
||||
|
||||
} else {
|
||||
posts.should.be.eql([
|
||||
{ id: 1, name: "Alex Messer" },
|
||||
{ id: 2, name: "Alex Messer" },
|
||||
{ id: 3, name: "Alex Messer" },
|
||||
]);
|
||||
}
|
||||
})));
|
||||
|
||||
it("should execute sub query in joins (using provided sub query builder)", () => Promise.all(connections.map(async connection => {
|
||||
@ -371,4 +392,4 @@ describe("query builder > sub-query", () => {
|
||||
]);
|
||||
})));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@ -36,7 +36,7 @@ describe("query runner > add column", () => {
|
||||
column1.isPrimary = true;
|
||||
|
||||
// MySql and Sqlite does not supports autoincrement composite primary keys.
|
||||
if (!(connection.driver instanceof MysqlDriver) && !(connection.driver instanceof AbstractSqliteDriver)) {
|
||||
if (!(connection.driver instanceof MysqlDriver) && !(connection.driver instanceof AbstractSqliteDriver) && !(connection.driver instanceof CockroachDriver)) {
|
||||
column1.isGenerated = true;
|
||||
column1.generationStrategy = "increment";
|
||||
}
|
||||
@ -62,7 +62,7 @@ describe("query runner > add column", () => {
|
||||
column1!.isPrimary.should.be.true;
|
||||
|
||||
// MySql and Sqlite does not supports autoincrement composite primary keys.
|
||||
if (!(connection.driver instanceof MysqlDriver) && !(connection.driver instanceof AbstractSqliteDriver)) {
|
||||
if (!(connection.driver instanceof MysqlDriver) && !(connection.driver instanceof AbstractSqliteDriver) && !(connection.driver instanceof CockroachDriver)) {
|
||||
column1!.isGenerated.should.be.true;
|
||||
column1!.generationStrategy!.should.be.equal("increment");
|
||||
}
|
||||
|
||||
@ -81,6 +81,9 @@ describe("query runner > change column", () => {
|
||||
|
||||
it("should correctly change column 'isGenerated' property and revert change", () => Promise.all(connections.map(async connection => {
|
||||
|
||||
if (connection.driver instanceof CockroachDriver)
|
||||
return;
|
||||
|
||||
const queryRunner = connection.createQueryRunner();
|
||||
let table = await queryRunner.getTable("post");
|
||||
let idColumn = table!.findColumnByName("id")!;
|
||||
@ -101,34 +104,31 @@ describe("query runner > change column", () => {
|
||||
table!.findColumnByName("id")!.isGenerated.should.be.false;
|
||||
expect(table!.findColumnByName("id")!.generationStrategy).to.be.undefined;
|
||||
|
||||
// CockroachDB does not allow changing primary key
|
||||
if (!(connection.driver instanceof CockroachDriver)) {
|
||||
table = await queryRunner.getTable("post");
|
||||
idColumn = table!.findColumnByName("id")!;
|
||||
changedIdColumn = idColumn.clone();
|
||||
changedIdColumn.isPrimary = false;
|
||||
await queryRunner.changeColumn(table!, idColumn, changedIdColumn);
|
||||
table = await queryRunner.getTable("post");
|
||||
idColumn = table!.findColumnByName("id")!;
|
||||
changedIdColumn = idColumn.clone();
|
||||
changedIdColumn.isPrimary = false;
|
||||
await queryRunner.changeColumn(table!, idColumn, changedIdColumn);
|
||||
|
||||
// check case when both primary and generated properties set to true
|
||||
table = await queryRunner.getTable("post");
|
||||
idColumn = table!.findColumnByName("id")!;
|
||||
changedIdColumn = idColumn.clone();
|
||||
changedIdColumn.isPrimary = true;
|
||||
changedIdColumn.isGenerated = true;
|
||||
changedIdColumn.generationStrategy = "increment";
|
||||
await queryRunner.changeColumn(table!, idColumn, changedIdColumn);
|
||||
// check case when both primary and generated properties set to true
|
||||
table = await queryRunner.getTable("post");
|
||||
idColumn = table!.findColumnByName("id")!;
|
||||
changedIdColumn = idColumn.clone();
|
||||
changedIdColumn.isPrimary = true;
|
||||
changedIdColumn.isGenerated = true;
|
||||
changedIdColumn.generationStrategy = "increment";
|
||||
await queryRunner.changeColumn(table!, idColumn, changedIdColumn);
|
||||
|
||||
table = await queryRunner.getTable("post");
|
||||
table!.findColumnByName("id")!.isGenerated.should.be.true;
|
||||
table!.findColumnByName("id")!.generationStrategy!.should.be.equal("increment");
|
||||
table = await queryRunner.getTable("post");
|
||||
table!.findColumnByName("id")!.isGenerated.should.be.true;
|
||||
table!.findColumnByName("id")!.generationStrategy!.should.be.equal("increment");
|
||||
|
||||
await queryRunner.executeMemoryDownSql();
|
||||
queryRunner.clearSqlMemory();
|
||||
await queryRunner.executeMemoryDownSql();
|
||||
queryRunner.clearSqlMemory();
|
||||
|
||||
table = await queryRunner.getTable("post");
|
||||
table!.findColumnByName("id")!.isGenerated.should.be.false;
|
||||
expect(table!.findColumnByName("id")!.generationStrategy).to.be.undefined;
|
||||
}
|
||||
table = await queryRunner.getTable("post");
|
||||
table!.findColumnByName("id")!.isGenerated.should.be.false;
|
||||
expect(table!.findColumnByName("id")!.generationStrategy).to.be.undefined;
|
||||
|
||||
await queryRunner.release();
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ describe("query runner > drop table", () => {
|
||||
connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
schemaCreate: true,
|
||||
dropSchema: true,
|
||||
});
|
||||
});
|
||||
beforeEach(() => reloadTestingDatabases(connections));
|
||||
|
||||
@ -5,7 +5,7 @@ import { PrimaryColumn } from "../../../../../src/decorator/columns/PrimaryColum
|
||||
@Entity()
|
||||
export class PostBigInt {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -16,4 +16,4 @@ export class PostBigInt {
|
||||
})
|
||||
counter: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import {PrimaryColumn} from "../../../../../src/decorator/columns/PrimaryColumn"
|
||||
@Entity()
|
||||
export class Post {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -17,4 +17,4 @@ export class Post {
|
||||
@Column()
|
||||
isNew: boolean = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,4 +2,4 @@ export interface User {
|
||||
id: number;
|
||||
firstName: string;
|
||||
secondName: string;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,4 +17,4 @@
|
||||
"nullable": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { PrimaryColumn } from "../../../../../src/decorator/columns/PrimaryColum
|
||||
@Entity()
|
||||
export class PostBigInt {
|
||||
|
||||
@PrimaryColumn("int")
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
@ -16,4 +16,4 @@ export class PostBigInt {
|
||||
})
|
||||
counter: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import "reflect-metadata";
|
||||
import {CockroachDriver} from "../../../src/driver/cockroachdb/CockroachDriver";
|
||||
import {closeTestingConnections, createTestingConnections} from "../../utils/test-utils";
|
||||
import {Connection} from "../../../src/connection/Connection";
|
||||
|
||||
@ -20,10 +21,18 @@ describe("github issues > #423 Cannot use Group as Table name && cannot autoSche
|
||||
await queryRunner.release();
|
||||
|
||||
table!.should.exist;
|
||||
table!.indices.length.should.be.equal(1);
|
||||
table!.indices[0].name!.should.be.equal("Groups name");
|
||||
table!.indices[0].columnNames[0].should.be.equal("name");
|
||||
table!.indices[0].isUnique!.should.be.true;
|
||||
|
||||
// CockroachDB stores unique indices as UNIQUE constraints
|
||||
if (connection.driver instanceof CockroachDriver) {
|
||||
table!.uniques.length.should.be.equal(1);
|
||||
table!.uniques[0].name!.should.be.equal("Groups name");
|
||||
table!.uniques[0].columnNames[0].should.be.equal("name");
|
||||
} else {
|
||||
table!.indices.length.should.be.equal(1);
|
||||
table!.indices[0].name!.should.be.equal("Groups name");
|
||||
table!.indices[0].columnNames[0].should.be.equal("name");
|
||||
table!.indices[0].isUnique!.should.be.true;
|
||||
}
|
||||
|
||||
})));
|
||||
|
||||
|
||||
@ -25,9 +25,9 @@ export class Post {
|
||||
@JoinColumn()
|
||||
category: PostCategory;
|
||||
|
||||
@Column("integer")
|
||||
@Column()
|
||||
updatedColumns: number = 0;
|
||||
|
||||
@Column("integer")
|
||||
@Column()
|
||||
updatedRelations: number = 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user