ph-dev-tools
Version:
Development Tools for PHibernate
95 lines (79 loc) • 2.92 kB
text/typescript
import {QEntityBuilder} from "./QEntityBuilder";
import {PropertyDocEntry, Decorator} from "../../parser/DocEntry";
import {QBuilder, getRelationFieldType} from "./../QBuilder";
import {OneToManyElements} from "phibernate/lib/index";
/**
* Created by Papa on 4/25/2016.
*/
const MANY_TO_ONE_DECORATOR = 'ManyToOne';
const ONE_TO_MANY_DECORATOR = 'OneToMany';
export class QRelationBuilder implements QBuilder {
constructor(
private parentBuilder:QEntityBuilder,
public entityProperty:PropertyDocEntry
) {
}
build():string {
let type = this.entityProperty.entity.type;
let qType = 'Q' + type;
this.parentBuilder.addImport(qType);
let definition;
let classQType = `Q${this.parentBuilder.entity.type}`;
let inverseRelationFieldName;
let name = this.entityProperty.name;
if (!this.entityProperty.isArray) {
this.ensureDecorator(MANY_TO_ONE_DECORATOR, 'ManyToOne');
inverseRelationFieldName = name;
} else {
let inverseRelation = this.getDecoratorValue<OneToManyElements>(ONE_TO_MANY_DECORATOR, 'OneToMany');
inverseRelationFieldName = inverseRelation.mappedBy;
}
let generisizedType = `QRelation<${qType}, ${type}, ${classQType}>`;
let relationType = getRelationFieldType(this.entityProperty);
let qClazz = `Q${this.parentBuilder.entity.docEntry.name}`;
definition = `${name} = new ${generisizedType}(this, ${qClazz}, RelationType.${relationType}, '${name}', ${type}, ${qType});`;
return definition;
}
buildInterfaceDefinition():string {
let type = this.entityProperty.entity.type;
let iqType = 'IQ' + type;
let classIQType = `IQ${this.parentBuilder.entity.type}`;
let generisizedType = `IQRelation<${iqType}, ${type}, ${classIQType}>`;
let iType = 'I' + type;
let definition = `${this.entityProperty.name}?: ${generisizedType} | ${iType}`;
return definition;
}
ensureDecorator(
decoratorName:string,
relationTypeDescription:string
):Decorator {
let decorators = this.entityProperty.decorators;
if (!decorators.length) {
throw `Expecting a @${decoratorName} decorator for ${relationTypeDescription} relation`;
}
let expectedDecorator:Decorator;
decorators.some((
decorator:Decorator
) => {
if (decorator.name === decoratorName) {
expectedDecorator = decorator;
return true;
}
});
if (!expectedDecorator) {
throw `Expecting a @${decoratorName} decorator for ${relationTypeDescription} relation`;
}
return expectedDecorator;
}
getDecoratorValue<V>(
decoratorName:string,
relationTypeDescription:string
):V {
let expectedDecorator = this.ensureDecorator(decoratorName, relationTypeDescription);
if (expectedDecorator.values.length != 1) {
throw `Expecting a single parameter on @${decoratorName} decorator`;
}
let parameter = expectedDecorator.values[0];
return parameter;
}
}