typeorm
Version:
Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB databases.
231 lines (229 loc) • 13.2 kB
JavaScript
import { __read, __spreadArray } from "tslib";
import { MysqlDriver } from "../driver/mysql/MysqlDriver";
import { ColumnMetadata } from "../metadata/ColumnMetadata";
import { EntityMetadata } from "../metadata/EntityMetadata";
import { ForeignKeyMetadata } from "../metadata/ForeignKeyMetadata";
import { IndexMetadata } from "../metadata/IndexMetadata";
import { AuroraDataApiDriver } from "../driver/aurora-data-api/AuroraDataApiDriver";
import { OracleDriver } from "../driver/oracle/OracleDriver";
import { TypeORMError } from "../error";
/**
* Creates EntityMetadata for junction tables.
* Junction tables are tables generated by many-to-many relations.
*/
var JunctionEntityMetadataBuilder = /** @class */ (function () {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
function JunctionEntityMetadataBuilder(connection) {
this.connection = connection;
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* Builds EntityMetadata for the junction of the given many-to-many relation.
*/
JunctionEntityMetadataBuilder.prototype.build = function (relation, joinTable) {
var _this = this;
var referencedColumns = this.collectReferencedColumns(relation, joinTable);
var inverseReferencedColumns = this.collectInverseReferencedColumns(relation, joinTable);
var joinTableName = joinTable.name || this.connection.namingStrategy.joinTableName(relation.entityMetadata.tableNameWithoutPrefix, relation.inverseEntityMetadata.tableNameWithoutPrefix, relation.propertyPath, relation.inverseRelation ? relation.inverseRelation.propertyName : "");
var entityMetadata = new EntityMetadata({
connection: this.connection,
args: {
target: "",
name: joinTableName,
type: "junction",
database: joinTable.database || relation.entityMetadata.database,
schema: joinTable.schema || relation.entityMetadata.schema,
}
});
entityMetadata.build();
// create original side junction columns
var junctionColumns = referencedColumns.map(function (referencedColumn) {
var joinColumn = joinTable.joinColumns ? joinTable.joinColumns.find(function (joinColumnArgs) {
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === referencedColumn.propertyName) &&
!!joinColumnArgs.name;
}) : undefined;
var columnName = joinColumn && joinColumn.name ? joinColumn.name
: _this.connection.namingStrategy.joinTableColumnName(relation.entityMetadata.tableNameWithoutPrefix, referencedColumn.propertyName, referencedColumn.databaseName);
return new ColumnMetadata({
connection: _this.connection,
entityMetadata: entityMetadata,
referencedColumn: referencedColumn,
args: {
target: "",
mode: "virtual",
propertyName: columnName,
options: {
name: columnName,
length: !referencedColumn.length
&& (_this.connection.driver instanceof MysqlDriver || _this.connection.driver instanceof AuroraDataApiDriver)
&& (referencedColumn.generationStrategy === "uuid" || referencedColumn.type === "uuid")
? "36"
: referencedColumn.length,
width: referencedColumn.width,
type: referencedColumn.type,
precision: referencedColumn.precision,
scale: referencedColumn.scale,
charset: referencedColumn.charset,
collation: referencedColumn.collation,
zerofill: referencedColumn.zerofill,
unsigned: referencedColumn.zerofill ? true : referencedColumn.unsigned,
enum: referencedColumn.enum,
enumName: referencedColumn.enumName,
nullable: false,
primary: true,
}
}
});
});
// create inverse side junction columns
var inverseJunctionColumns = inverseReferencedColumns.map(function (inverseReferencedColumn) {
var joinColumn = joinTable.inverseJoinColumns ? joinTable.inverseJoinColumns.find(function (joinColumnArgs) {
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === inverseReferencedColumn.propertyName) &&
!!joinColumnArgs.name;
}) : undefined;
var columnName = joinColumn && joinColumn.name ? joinColumn.name
: _this.connection.namingStrategy.joinTableInverseColumnName(relation.inverseEntityMetadata.tableNameWithoutPrefix, inverseReferencedColumn.propertyName, inverseReferencedColumn.databaseName);
return new ColumnMetadata({
connection: _this.connection,
entityMetadata: entityMetadata,
referencedColumn: inverseReferencedColumn,
args: {
target: "",
mode: "virtual",
propertyName: columnName,
options: {
length: !inverseReferencedColumn.length
&& (_this.connection.driver instanceof MysqlDriver || _this.connection.driver instanceof AuroraDataApiDriver)
&& (inverseReferencedColumn.generationStrategy === "uuid" || inverseReferencedColumn.type === "uuid")
? "36"
: inverseReferencedColumn.length,
width: inverseReferencedColumn.width,
type: inverseReferencedColumn.type,
precision: inverseReferencedColumn.precision,
scale: inverseReferencedColumn.scale,
charset: inverseReferencedColumn.charset,
collation: inverseReferencedColumn.collation,
zerofill: inverseReferencedColumn.zerofill,
unsigned: inverseReferencedColumn.zerofill ? true : inverseReferencedColumn.unsigned,
enum: inverseReferencedColumn.enum,
enumName: inverseReferencedColumn.enumName,
name: columnName,
nullable: false,
primary: true,
}
}
});
});
this.changeDuplicatedColumnNames(junctionColumns, inverseJunctionColumns);
// set junction table columns
entityMetadata.ownerColumns = junctionColumns;
entityMetadata.inverseColumns = inverseJunctionColumns;
entityMetadata.ownColumns = __spreadArray(__spreadArray([], __read(junctionColumns)), __read(inverseJunctionColumns));
entityMetadata.ownColumns.forEach(function (column) { return column.relationMetadata = relation; });
// create junction table foreign keys
// Note: UPDATE CASCADE clause is not supported in Oracle.
entityMetadata.foreignKeys = relation.createForeignKeyConstraints ? [
new ForeignKeyMetadata({
entityMetadata: entityMetadata,
referencedEntityMetadata: relation.entityMetadata,
columns: junctionColumns,
referencedColumns: referencedColumns,
onDelete: relation.onDelete || "CASCADE",
onUpdate: this.connection.driver instanceof OracleDriver ? "NO ACTION" : relation.onUpdate || "CASCADE",
}),
new ForeignKeyMetadata({
entityMetadata: entityMetadata,
referencedEntityMetadata: relation.inverseEntityMetadata,
columns: inverseJunctionColumns,
referencedColumns: inverseReferencedColumns,
onDelete: relation.inverseRelation ? relation.inverseRelation.onDelete : "CASCADE",
onUpdate: this.connection.driver instanceof OracleDriver
? "NO ACTION"
: relation.inverseRelation
? relation.inverseRelation.onUpdate
: "CASCADE",
}),
] : [];
// create junction table indices
entityMetadata.ownIndices = [
new IndexMetadata({
entityMetadata: entityMetadata,
columns: junctionColumns,
args: {
target: entityMetadata.target,
synchronize: true
}
}),
new IndexMetadata({
entityMetadata: entityMetadata,
columns: inverseJunctionColumns,
args: {
target: entityMetadata.target,
synchronize: true
}
})
];
// finally return entity metadata
return entityMetadata;
};
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* Collects referenced columns from the given join column args.
*/
JunctionEntityMetadataBuilder.prototype.collectReferencedColumns = function (relation, joinTable) {
var hasAnyReferencedColumnName = joinTable.joinColumns ? joinTable.joinColumns.find(function (joinColumn) { return !!joinColumn.referencedColumnName; }) : false;
if (!joinTable.joinColumns || (joinTable.joinColumns && !hasAnyReferencedColumnName)) {
return relation.entityMetadata.columns.filter(function (column) { return column.isPrimary; });
}
else {
return joinTable.joinColumns.map(function (joinColumn) {
var referencedColumn = relation.entityMetadata.columns.find(function (column) { return column.propertyName === joinColumn.referencedColumnName; });
if (!referencedColumn)
throw new TypeORMError("Referenced column " + joinColumn.referencedColumnName + " was not found in entity " + relation.entityMetadata.name);
return referencedColumn;
});
}
};
/**
* Collects inverse referenced columns from the given join column args.
*/
JunctionEntityMetadataBuilder.prototype.collectInverseReferencedColumns = function (relation, joinTable) {
var hasInverseJoinColumns = !!joinTable.inverseJoinColumns;
var hasAnyInverseReferencedColumnName = hasInverseJoinColumns ? joinTable.inverseJoinColumns.find(function (joinColumn) { return !!joinColumn.referencedColumnName; }) : false;
if (!hasInverseJoinColumns || (hasInverseJoinColumns && !hasAnyInverseReferencedColumnName)) {
return relation.inverseEntityMetadata.primaryColumns;
}
else {
return joinTable.inverseJoinColumns.map(function (joinColumn) {
var referencedColumn = relation.inverseEntityMetadata.ownColumns.find(function (column) { return column.propertyName === joinColumn.referencedColumnName; });
if (!referencedColumn)
throw new TypeORMError("Referenced column " + joinColumn.referencedColumnName + " was not found in entity " + relation.inverseEntityMetadata.name);
return referencedColumn;
});
}
};
JunctionEntityMetadataBuilder.prototype.changeDuplicatedColumnNames = function (junctionColumns, inverseJunctionColumns) {
var _this = this;
junctionColumns.forEach(function (junctionColumn) {
inverseJunctionColumns.forEach(function (inverseJunctionColumn) {
if (junctionColumn.givenDatabaseName === inverseJunctionColumn.givenDatabaseName) {
var junctionColumnName = _this.connection.namingStrategy.joinTableColumnDuplicationPrefix(junctionColumn.propertyName, 1);
junctionColumn.propertyName = junctionColumnName;
junctionColumn.givenDatabaseName = junctionColumnName;
var inverseJunctionColumnName = _this.connection.namingStrategy.joinTableColumnDuplicationPrefix(inverseJunctionColumn.propertyName, 2);
inverseJunctionColumn.propertyName = inverseJunctionColumnName;
inverseJunctionColumn.givenDatabaseName = inverseJunctionColumnName;
}
});
});
};
return JunctionEntityMetadataBuilder;
}());
export { JunctionEntityMetadataBuilder };
//# sourceMappingURL=JunctionEntityMetadataBuilder.js.map