import { EntityData, EntityProperty, IEntity, IEntityType, IPrimaryKey } from '../decorators'; import { Hydrator } from './Hydrator'; import { Collection, ReferenceType } from '../entity'; import { Utils } from '../utils'; export class ObjectHydrator extends Hydrator { protected hydrateProperty>(entity: T, prop: EntityProperty, value: any): void { if (prop.reference === ReferenceType.MANY_TO_ONE || prop.reference === ReferenceType.ONE_TO_ONE) { this.hydrateManyToOne(value, entity, prop); } else if (prop.reference === ReferenceType.ONE_TO_MANY) { this.hydrateOneToMany(entity, prop, value); } else if (prop.reference === ReferenceType.MANY_TO_MANY) { this.hydrateManyToMany(entity, prop, value); } else if (value) { // ReferenceType.SCALAR this.hydrateScalar(entity, prop, value); } } private hydrateOneToMany>(entity: T, prop: EntityProperty, value: any): void { entity[prop.name as keyof T] = new Collection(entity, undefined, !!value) as T[keyof T]; } private hydrateScalar>(entity: T, prop: EntityProperty, value: any): void { entity[prop.name as keyof T] = value; } private hydrateManyToMany>(entity: T, prop: EntityProperty, value: any): void { if (prop.owner) { return this.hydrateManyToManyOwner(entity, prop, value); } else if (!entity[prop.name as keyof T]) { this.hydrateManyToManyInverse(entity, prop); } } private hydrateManyToManyOwner>(entity: T, prop: EntityProperty, value: any): void { if (Array.isArray(value)) { const items = value.map((value: IPrimaryKey | EntityData) => this.createCollectionItem(prop, value)); entity[prop.name as keyof T] = new Collection(entity, items) as T[keyof T]; } else if (!entity[prop.name as keyof T]) { const items = this.driver.getPlatform().usesPivotTable() ? undefined : []; entity[prop.name as keyof T] = new Collection(entity, items, false) as T[keyof T]; } } private hydrateManyToManyInverse>(entity: T, prop: EntityProperty): void { if (!entity[prop.name as keyof T]) { entity[prop.name as keyof T] = new Collection(entity, undefined, false) as T[keyof T]; } } private hydrateManyToOne>(value: any, entity: T, prop: EntityProperty): void { if (!value) { return; } if (Utils.isPrimaryKey(value)) { entity[prop.name as keyof T] = this.factory.createReference(prop.type, value); return; } if (Utils.isObject(value)) { entity[prop.name as keyof T] = this.factory.create(prop.type, value); } } private createCollectionItem>(prop: EntityProperty, value: IPrimaryKey | EntityData): T { if (Utils.isPrimaryKey(value)) { return this.factory.createReference(prop.type, value); } const child = this.factory.create(prop.type, value as EntityData); child.__em.merge(child); return child; } }