mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added support of embeddables
This commit is contained in:
parent
249b30bc91
commit
342b560ad9
@ -23,41 +23,35 @@ const options: CreateConnectionOptions = {
|
||||
|
||||
createConnection(options).then(connection => {
|
||||
|
||||
let postRepository = connection.getRepository(Post);
|
||||
let questionRepository = connection.getRepository(Question);
|
||||
|
||||
const question = new Question();
|
||||
question.title = "Hello question!";
|
||||
question.counters = new Counters();
|
||||
question.counters.stars = 5;
|
||||
question.counters.raiting = 10;
|
||||
question.counters.commentCount = 3;
|
||||
question.counters.metadata = "#question #question-counter";
|
||||
|
||||
const questionPromise = questionRepository.findOneById(1).then(question => {
|
||||
if (!question) {
|
||||
question = new Question();
|
||||
question.title = "Umed";
|
||||
return questionRepository.persist(question).then(savedAuthor => {
|
||||
return questionRepository.findOneById(1);
|
||||
});
|
||||
}
|
||||
return question;
|
||||
});
|
||||
|
||||
const postPromise = postRepository.findOneById(1).then(post => {
|
||||
if (!post) {
|
||||
post = new Post();
|
||||
post.title = "Hello post";
|
||||
post.text = "This is post contents";
|
||||
return postRepository.persist(post).then(savedPost => {
|
||||
return postRepository.findOneById(1);
|
||||
});
|
||||
}
|
||||
return post;
|
||||
});
|
||||
|
||||
return Promise.all<any>([questionPromise, postPromise])
|
||||
.then(results => {
|
||||
const [question, post] = results;
|
||||
question.posts = [post];
|
||||
return questionRepository.persist(question);
|
||||
questionRepository
|
||||
.persist(question)
|
||||
.then(savedQuestion => {
|
||||
console.log("question has been saved: ", savedQuestion);
|
||||
|
||||
// lets load it now:
|
||||
return questionRepository.findOneById(savedQuestion.id);
|
||||
})
|
||||
.then(savedAuthor => {
|
||||
console.log("Question has been saved: ", savedAuthor);
|
||||
.then(loadedQuestion => {
|
||||
console.log("question has been loaded: ", loadedQuestion);
|
||||
|
||||
loadedQuestion.counters.commentCount = 7;
|
||||
loadedQuestion.counters.metadata = "#updated question";
|
||||
|
||||
return questionRepository.persist(loadedQuestion);
|
||||
})
|
||||
.catch(error => console.log(error.stack));
|
||||
.then(updatedQuestion => {
|
||||
console.log("question has been updated: ", updatedQuestion);
|
||||
})
|
||||
.catch(e => console.log(e));
|
||||
|
||||
}, error => console.log("Cannot connect: ", error));
|
||||
@ -8,7 +8,6 @@ export function EmbeddableTable(): Function {
|
||||
return function (target: Function) {
|
||||
const args: TableMetadataArgs = {
|
||||
target: target,
|
||||
name: name,
|
||||
type: "embeddable"
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
|
||||
@ -39,15 +39,15 @@ export class EntityMetadataBuilder {
|
||||
|
||||
const embeddableMergedArgs = getMetadataArgsStorage().getMergedEmbeddableTableMetadatas(entityClasses);
|
||||
const entityMetadatas = getMetadataArgsStorage().getMergedTableMetadatas(entityClasses).map(mergedArgs => {
|
||||
|
||||
|
||||
// find embeddable tables for embeddeds registered in this table and create EmbeddedMetadatas from them
|
||||
const embeddeds: EmbeddedMetadata[] = [];
|
||||
mergedArgs.embeddeds.forEach(embedded => {
|
||||
const embeddableTable = embeddableMergedArgs.find(mergedArs => mergedArgs.table.target === embedded.type);
|
||||
const embeddableTable = embeddableMergedArgs.find(mergedArgs => mergedArgs.table.target === embedded.type());
|
||||
if (embeddableTable) {
|
||||
const table = new TableMetadata(mergedArgs.table);
|
||||
const columns = mergedArgs.columns.map(args => new ColumnMetadata(args));
|
||||
embeddeds.push(new EmbeddedMetadata(table, columns));
|
||||
const table = new TableMetadata(embeddableTable.table);
|
||||
const columns = embeddableTable.columns.map(args => new ColumnMetadata(args));
|
||||
embeddeds.push(new EmbeddedMetadata(embedded.type(), embedded.propertyName, table, columns));
|
||||
}
|
||||
});
|
||||
|
||||
@ -135,8 +135,7 @@ export class EntityMetadataBuilder {
|
||||
nullable: relation.isNullable
|
||||
}
|
||||
});
|
||||
relationalColumn.entityMetadata = metadata;
|
||||
metadata.columns.push(relationalColumn);
|
||||
metadata.addColumn(relationalColumn);
|
||||
}
|
||||
|
||||
// create and add foreign key
|
||||
|
||||
@ -2,6 +2,7 @@ import {PropertyMetadata} from "./PropertyMetadata";
|
||||
import {ColumnMetadataArgs} from "../metadata-args/ColumnMetadataArgs";
|
||||
import {ColumnType} from "./types/ColumnTypes";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {EmbeddedMetadata} from "./EmbeddedMetadata";
|
||||
|
||||
/**
|
||||
* Kinda type of the column. Not a type in the database, but locally used type to determine what kind of column
|
||||
@ -23,6 +24,11 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
*/
|
||||
entityMetadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* Embedded metadata where this column metadata is.
|
||||
*/
|
||||
embeddedMetadata: EmbeddedMetadata;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public Readonly Properties
|
||||
// ---------------------------------------------------------------------
|
||||
@ -109,19 +115,8 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
constructor(args: ColumnMetadataArgs);
|
||||
constructor(entityMetadata: EntityMetadata, args: ColumnMetadataArgs);
|
||||
constructor(entityMetadataOrArgs: EntityMetadata|ColumnMetadataArgs, args?: ColumnMetadataArgs) {
|
||||
super(
|
||||
args ? args.target : (entityMetadataOrArgs as ColumnMetadataArgs).target,
|
||||
args ? args.propertyName : (entityMetadataOrArgs as ColumnMetadataArgs).propertyName
|
||||
);
|
||||
|
||||
if (entityMetadataOrArgs && args) {
|
||||
this.entityMetadata = entityMetadataOrArgs as EntityMetadata;
|
||||
}
|
||||
|
||||
args = args ? args : entityMetadataOrArgs as ColumnMetadataArgs;
|
||||
constructor(args: ColumnMetadataArgs) {
|
||||
super(args.target, args.propertyName);
|
||||
|
||||
if (args.mode)
|
||||
this.mode = args.mode;
|
||||
@ -163,12 +158,30 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
*/
|
||||
get name(): string {
|
||||
|
||||
// if custom column name is set implicitly then return it
|
||||
if (this._name)
|
||||
return this.entityMetadata.namingStrategy.columnNameCustomized(this._name);
|
||||
// if this column is embedded's column then apply different entity
|
||||
if (this.embeddedMetadata) {
|
||||
if (this._name)
|
||||
return this.embeddedMetadata.entityMetadata.namingStrategy.embeddedColumnNameCustomized(this.embeddedMetadata.propertyName, this._name);
|
||||
|
||||
// if there is a naming strategy then use it to normalize propertyName as column name
|
||||
return this.entityMetadata.namingStrategy.columnName(this.propertyName);
|
||||
return this.embeddedMetadata.entityMetadata.namingStrategy.embeddedColumnName(this.embeddedMetadata.propertyName, this.propertyName);
|
||||
}
|
||||
|
||||
if (this.entityMetadata) {
|
||||
if (this._name)
|
||||
return this.entityMetadata.namingStrategy.columnNameCustomized(this._name);
|
||||
|
||||
// if there is a naming strategy then use it to normalize propertyName as column name
|
||||
return this.entityMetadata.namingStrategy.columnName(this.propertyName);
|
||||
}
|
||||
|
||||
throw new Error(`Column${this._name ? this._name + " " : ""} is not attached to any entity or embedded.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this column is in embedded, not directly in the table.
|
||||
*/
|
||||
get isInEmbedded(): boolean {
|
||||
return !!this.embeddedMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,4 +219,39 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
return this.mode === "version";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets embedded property in which column is.
|
||||
*/
|
||||
get embeddedProperty() {
|
||||
if (!this.embeddedMetadata)
|
||||
throw new Error(`This column${ this._name ? this._name + " " : "" } is not in embedded entity.`);
|
||||
|
||||
return this.embeddedMetadata.propertyName;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
hasEntityValue(entity: any) {
|
||||
if (!entity)
|
||||
return false;
|
||||
|
||||
if (this.isInEmbedded) {
|
||||
return entity.hasOwnProperty(this.embeddedProperty) &&
|
||||
entity[this.embeddedProperty].hasOwnProperty(this.propertyName);
|
||||
|
||||
} else {
|
||||
return entity.hasOwnProperty(this.propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
getEntityValue(entity: any) {
|
||||
if (this.isInEmbedded) {
|
||||
return entity[this.embeddedProperty][this.propertyName];
|
||||
} else {
|
||||
return entity[this.propertyName];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -20,6 +20,11 @@ export class EmbeddedMetadata {
|
||||
// Private Properties
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Property name on which this embedded is attached.
|
||||
*/
|
||||
readonly propertyName: string;
|
||||
|
||||
/**
|
||||
* Embeddable table.
|
||||
*/
|
||||
@ -30,13 +35,34 @@ export class EmbeddedMetadata {
|
||||
*/
|
||||
readonly columns: ColumnMetadata[];
|
||||
|
||||
/**
|
||||
* Embedded type.
|
||||
*/
|
||||
readonly type: Function;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
constructor(table: TableMetadata, columns: ColumnMetadata[]) {
|
||||
constructor(type: Function, propertyName: string, table: TableMetadata, columns: ColumnMetadata[]) {
|
||||
this.type = type;
|
||||
this.propertyName = propertyName;
|
||||
this.table = table;
|
||||
this.columns = columns;
|
||||
this.columns.forEach(column => {
|
||||
column.embeddedMetadata = this;
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a new embedded object.
|
||||
*/
|
||||
create() {
|
||||
return new (this.type as any);
|
||||
}
|
||||
|
||||
}
|
||||
@ -36,11 +36,6 @@ export class EntityMetadata {
|
||||
*/
|
||||
readonly table: TableMetadata;
|
||||
|
||||
/**
|
||||
* Entity's column metadatas.
|
||||
*/
|
||||
readonly columns: ColumnMetadata[];
|
||||
|
||||
/**
|
||||
* Entity's relation metadatas.
|
||||
*/
|
||||
@ -61,6 +56,15 @@ export class EntityMetadata {
|
||||
*/
|
||||
readonly embeddeds: EmbeddedMetadata[];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Entity's column metadatas.
|
||||
*/
|
||||
private readonly _columns: ColumnMetadata[];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
@ -68,14 +72,14 @@ export class EntityMetadata {
|
||||
constructor(args: EntityMetadataArgs) {
|
||||
this.namingStrategy = args.namingStrategy;
|
||||
this.table = args.tableMetadata;
|
||||
this.columns = args.columnMetadatas || [];
|
||||
this._columns = args.columnMetadatas || [];
|
||||
this.relations = args.relationMetadatas || [];
|
||||
this.indices = args.indexMetadatas || [];
|
||||
this.foreignKeys = args.foreignKeyMetadatas || [];
|
||||
this.embeddeds = args.embeddedMetadatas || [];
|
||||
|
||||
this.table.entityMetadata = this;
|
||||
this.columns.forEach(column => column.entityMetadata = this);
|
||||
this._columns.forEach(column => column.entityMetadata = this);
|
||||
this.relations.forEach(relation => relation.entityMetadata = this);
|
||||
this.foreignKeys.forEach(foreignKey => foreignKey.entityMetadata = this);
|
||||
this.indices.forEach(index => index.entityMetadata = this);
|
||||
@ -99,6 +103,17 @@ export class EntityMetadata {
|
||||
return this.table.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* All columns of the entity, including columns that are coming from the embeddeds of this entity.
|
||||
*/
|
||||
get columns() {
|
||||
let allColumns: ColumnMetadata[] = [].concat(this._columns);
|
||||
this.embeddeds.forEach(embedded => {
|
||||
allColumns = allColumns.concat(embedded.columns);
|
||||
});
|
||||
return allColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Target class to which this entity metadata is bind.
|
||||
*/
|
||||
@ -111,14 +126,14 @@ export class EntityMetadata {
|
||||
* Special entity metadatas like for junction tables and closure junction tables don't have a primary column.
|
||||
*/
|
||||
get hasPrimaryColumn(): boolean {
|
||||
return !!this.columns.find(column => column.isPrimary);
|
||||
return !!this._columns.find(column => column.isPrimary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the primary column.
|
||||
*/
|
||||
get primaryColumn(): ColumnMetadata {
|
||||
const primaryKey = this.columns.find(column => column.isPrimary);
|
||||
const primaryKey = this._columns.find(column => column.isPrimary);
|
||||
if (!primaryKey)
|
||||
throw new Error(`Primary key is not set for the ${this.name} entity.`);
|
||||
|
||||
@ -129,14 +144,14 @@ export class EntityMetadata {
|
||||
* Checks if entity has a create date column.
|
||||
*/
|
||||
get hasCreateDateColumn(): boolean {
|
||||
return !!this.columns.find(column => column.mode === "createDate");
|
||||
return !!this._columns.find(column => column.mode === "createDate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets entity column which contains a create date value.
|
||||
*/
|
||||
get createDateColumn(): ColumnMetadata {
|
||||
const column = this.columns.find(column => column.mode === "createDate");
|
||||
const column = this._columns.find(column => column.mode === "createDate");
|
||||
if (!column)
|
||||
throw new Error(`CreateDateColumn was not found in entity ${this.name}`);
|
||||
|
||||
@ -147,14 +162,14 @@ export class EntityMetadata {
|
||||
* Checks if entity has an update date column.
|
||||
*/
|
||||
get hasUpdateDateColumn(): boolean {
|
||||
return !!this.columns.find(column => column.mode === "updateDate");
|
||||
return !!this._columns.find(column => column.mode === "updateDate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets entity column which contains an update date value.
|
||||
*/
|
||||
get updateDateColumn(): ColumnMetadata {
|
||||
const column = this.columns.find(column => column.mode === "updateDate");
|
||||
const column = this._columns.find(column => column.mode === "updateDate");
|
||||
if (!column)
|
||||
throw new Error(`UpdateDateColumn was not found in entity ${this.name}`);
|
||||
|
||||
@ -165,14 +180,14 @@ export class EntityMetadata {
|
||||
* Checks if entity has a version column.
|
||||
*/
|
||||
get hasVersionColumn(): boolean {
|
||||
return !!this.columns.find(column => column.mode === "version");
|
||||
return !!this._columns.find(column => column.mode === "version");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets entity column which contains an entity version.
|
||||
*/
|
||||
get versionColumn(): ColumnMetadata {
|
||||
const column = this.columns.find(column => column.mode === "version");
|
||||
const column = this._columns.find(column => column.mode === "version");
|
||||
if (!column)
|
||||
throw new Error(`VersionColumn was not found in entity ${this.name}`);
|
||||
|
||||
@ -183,11 +198,11 @@ export class EntityMetadata {
|
||||
* Checks if entity has a tree level column.
|
||||
*/
|
||||
get hasTreeLevelColumn(): boolean {
|
||||
return !!this.columns.find(column => column.mode === "treeLevel");
|
||||
return !!this._columns.find(column => column.mode === "treeLevel");
|
||||
}
|
||||
|
||||
get treeLevelColumn(): ColumnMetadata {
|
||||
const column = this.columns.find(column => column.mode === "treeLevel");
|
||||
const column = this._columns.find(column => column.mode === "treeLevel");
|
||||
if (!column)
|
||||
throw new Error(`TreeLevelColumn was not found in entity ${this.name}`);
|
||||
|
||||
@ -243,6 +258,42 @@ export class EntityMetadata {
|
||||
return this.ownerOneToOneRelations.concat(this.manyToOneRelations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a tree parent relation. Used only in tree-tables.
|
||||
*/
|
||||
get hasTreeParentRelation() {
|
||||
return !!this.relations.find(relation => relation.isTreeParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree parent relation. Used only in tree-tables.
|
||||
*/
|
||||
get treeParentRelation() {
|
||||
const relation = this.relations.find(relation => relation.isTreeParent);
|
||||
if (!relation)
|
||||
throw new Error(`TreeParent relation was not found in entity ${this.name}`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a tree children relation. Used only in tree-tables.
|
||||
*/
|
||||
get hasTreeChildrenRelation() {
|
||||
return !!this.relations.find(relation => relation.isTreeChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree children relation. Used only in tree-tables.
|
||||
*/
|
||||
get treeChildrenRelation() {
|
||||
const relation = this.relations.find(relation => relation.isTreeChildren);
|
||||
if (!relation)
|
||||
throw new Error(`TreeParent relation was not found in entity ${this.name}`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -259,7 +310,7 @@ export class EntityMetadata {
|
||||
*/
|
||||
createPropertiesMap(): { [name: string]: string|any } {
|
||||
const entity: { [name: string]: string|any } = {};
|
||||
this.columns.forEach(column => entity[column.propertyName] = column.propertyName);
|
||||
this._columns.forEach(column => entity[column.propertyName] = column.propertyName);
|
||||
this.relations.forEach(relation => entity[relation.propertyName] = relation.propertyName);
|
||||
return entity;
|
||||
}
|
||||
@ -282,14 +333,14 @@ export class EntityMetadata {
|
||||
* Checks if column with the given property name exist.
|
||||
*/
|
||||
hasColumnWithPropertyName(propertyName: string): boolean {
|
||||
return !!this.columns.find(column => column.propertyName === propertyName);
|
||||
return !!this._columns.find(column => column.propertyName === propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if column with the given database name exist.
|
||||
*/
|
||||
hasColumnWithDbName(name: string): boolean {
|
||||
return !!this.columns.find(column => column.name === name);
|
||||
return !!this._columns.find(column => column.name === name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,41 +378,10 @@ export class EntityMetadata {
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a tree parent relation. Used only in tree-tables.
|
||||
*/
|
||||
get hasTreeParentRelation() {
|
||||
return !!this.relations.find(relation => relation.isTreeParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree parent relation. Used only in tree-tables.
|
||||
*/
|
||||
get treeParentRelation() {
|
||||
const relation = this.relations.find(relation => relation.isTreeParent);
|
||||
if (!relation)
|
||||
throw new Error(`TreeParent relation was not found in entity ${this.name}`);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a tree children relation. Used only in tree-tables.
|
||||
*/
|
||||
get hasTreeChildrenRelation() {
|
||||
return !!this.relations.find(relation => relation.isTreeChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree children relation. Used only in tree-tables.
|
||||
*/
|
||||
get treeChildrenRelation() {
|
||||
const relation = this.relations.find(relation => relation.isTreeChildren);
|
||||
if (!relation)
|
||||
throw new Error(`TreeParent relation was not found in entity ${this.name}`);
|
||||
|
||||
return relation;
|
||||
|
||||
addColumn(column: ColumnMetadata) {
|
||||
this._columns.push(column);
|
||||
column.entityMetadata = this;
|
||||
}
|
||||
|
||||
}
|
||||
@ -22,6 +22,14 @@ export class DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
return customName;
|
||||
}
|
||||
|
||||
embeddedColumnName(embeddedPropertyName: string, columnPropertyName: string): string {
|
||||
return embeddedPropertyName + "_" + columnPropertyName;
|
||||
}
|
||||
|
||||
embeddedColumnNameCustomized(embeddedPropertyName: string, columnCustomName: string): string {
|
||||
return embeddedPropertyName + "_" + columnCustomName;
|
||||
}
|
||||
|
||||
relationName(propertyName: string): string {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
@ -24,6 +24,16 @@ export interface NamingStrategyInterface {
|
||||
*/
|
||||
columnNameCustomized(customName: string): string;
|
||||
|
||||
/**
|
||||
* Gets the embedded's column name from the given property name.
|
||||
*/
|
||||
embeddedColumnName(embeddedPropertyName: string, columnPropertyName: string): string;
|
||||
|
||||
/**
|
||||
* Gets the embedded's column name from the given custom column name.
|
||||
*/
|
||||
embeddedColumnNameCustomized(embeddedPropertyName: string, columnCustomName: string): string;
|
||||
|
||||
/**
|
||||
* Gets the table's relation name from the given property name.
|
||||
*/
|
||||
|
||||
@ -416,10 +416,10 @@ export class EntityPersistOperationBuilder {
|
||||
private diffColumns(metadata: EntityMetadata, newEntity: any, dbEntity: any) {
|
||||
return metadata.columns
|
||||
.filter(column => !column.isVirtual && !column.isUpdateDate && !column.isVersion && !column.isCreateDate)
|
||||
.filter(column => newEntity[column.propertyName] !== dbEntity[column.propertyName])
|
||||
.filter(column => column.getEntityValue(newEntity) !== column.getEntityValue(dbEntity))
|
||||
.filter(column => {
|
||||
// filter out "relational columns" only in the case if there is a relation object in entity
|
||||
if (metadata.hasRelationWithDbName(column.propertyName)) {
|
||||
if (!column.isInEmbedded && metadata.hasRelationWithDbName(column.propertyName)) {
|
||||
const relation = metadata.findRelationWithDbName(column.propertyName);
|
||||
if (newEntity[relation.propertyName] !== null && newEntity[relation.propertyName] !== undefined)
|
||||
return false;
|
||||
|
||||
@ -9,6 +9,7 @@ import {Broadcaster} from "../subscriber/Broadcaster";
|
||||
import {EntityMetadataCollection} from "../metadata-args/collection/EntityMetadataCollection";
|
||||
import {Driver} from "../driver/Driver";
|
||||
import {UpdateByInverseSideOperation} from "./operation/UpdateByInverseSideOperation";
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
|
||||
/**
|
||||
* Executes PersistOperation in the given connection.
|
||||
@ -353,7 +354,7 @@ export class PersistOperationExecutor {
|
||||
const values: { [key: string]: any } = {};
|
||||
|
||||
updateOperation.columns.forEach(column => {
|
||||
values[column.name] = this.driver.preparePersistentValue(entity[column.propertyName], column);
|
||||
values[column.name] = this.driver.preparePersistentValue(column.getEntityValue(entity), column);
|
||||
});
|
||||
|
||||
updateOperation.relations.forEach(relation => {
|
||||
@ -393,14 +394,13 @@ export class PersistOperationExecutor {
|
||||
private insert(operation: InsertOperation) {
|
||||
const entity = operation.entity;
|
||||
const metadata = this.entityMetadatas.findByTarget(entity.constructor);
|
||||
|
||||
const columns = metadata.columns
|
||||
.filter(column => !column.isVirtual)
|
||||
.filter(column => entity.hasOwnProperty(column.propertyName))
|
||||
.map(column => column.name);
|
||||
const values = metadata.columns
|
||||
.filter(column => !column.isVirtual)
|
||||
.filter(column => entity.hasOwnProperty(column.propertyName))
|
||||
.map(column => this.driver.preparePersistentValue(entity[column.propertyName], column));
|
||||
.filter(column => !column.isVirtual && column.hasEntityValue(entity));
|
||||
|
||||
const columnNames = columns.map(column => column.name);
|
||||
const values = columns.map(column => this.driver.preparePersistentValue(column.getEntityValue(entity), column));
|
||||
|
||||
const relationColumns = metadata.relations
|
||||
.filter(relation => relation.isOwning && !!relation.inverseEntityMetadata)
|
||||
.filter(relation => entity.hasOwnProperty(relation.propertyName))
|
||||
@ -413,7 +413,7 @@ export class PersistOperationExecutor {
|
||||
.filter(relation => entity[relation.propertyName].hasOwnProperty(relation.inverseEntityMetadata.primaryColumn.propertyName))
|
||||
.map(relation => entity[relation.propertyName][relation.inverseEntityMetadata.primaryColumn.propertyName]);
|
||||
|
||||
const allColumns = columns.concat(relationColumns);
|
||||
const allColumns = columnNames.concat(relationColumns);
|
||||
const allValues = values.concat(relationValues);
|
||||
|
||||
if (metadata.hasCreateDateColumn) {
|
||||
|
||||
@ -81,7 +81,16 @@ export class RawSqlResultsToEntityTransformer {
|
||||
metadata.columns.forEach(column => {
|
||||
const valueInObject = alias.getColumnValue(rawSqlResults[0], column.name); // we use zero index since its grouped data
|
||||
if (valueInObject && column.propertyName && !column.isVirtual) {
|
||||
entity[column.propertyName] = this.driver.prepareHydratedValue(valueInObject, column);
|
||||
const value = this.driver.prepareHydratedValue(valueInObject, column);
|
||||
|
||||
if (column.isInEmbedded) {
|
||||
if (!entity[column.embeddedProperty])
|
||||
entity[column.embeddedProperty] = column.embeddedMetadata.create();
|
||||
|
||||
entity[column.embeddedProperty][column.propertyName] = value;
|
||||
} else {
|
||||
entity[column.propertyName] = value;
|
||||
}
|
||||
hasData = true;
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user