package joist.codegen.passes;
import joist.codegen.Codegen;
import joist.codegen.dtos.Entity;
import joist.codegen.dtos.ManyToOneProperty;
import joist.codegen.dtos.OneToManyProperty;
import joist.codegen.dtos.PrimitiveProperty;
import joist.domain.orm.queries.Select;
import joist.sourcegen.Argument;
import joist.sourcegen.GClass;
import joist.sourcegen.GMethod;
import joist.util.Copy;
public class GenerateQueriesCodegenPass implements Pass<Codegen> {
public void pass(Codegen codegen) {
for (Entity entity : codegen.getSchema().getEntities().values()) {
if (entity.isCodeEntity()) {
continue;
}
GClass queriesCodegen = this.createCodegenOutput(codegen, entity);
this.setupBaseClassAndConstructor(codegen, entity, queriesCodegen);
this.addDelete(entity, queriesCodegen);
this.addFindByForUniquePrimitives(entity, queriesCodegen);
this.addFindByForCodes(entity, queriesCodegen);
this.addFindIdForSkippedCollections(entity, queriesCodegen);
}
}
private GClass createCodegenOutput(Codegen codegen, Entity entity) {
return codegen.getOutputCodegenDirectory().getClass(entity.getFullQueriesCodegenClassName());
}
private void setupBaseClassAndConstructor(Codegen codegen, Entity entity, GClass queriesCodegen) {
queriesCodegen.setAbstract().setPackagePrivate();
queriesCodegen.baseClassName(codegen.getConfig().getQueriesBaseClass(), entity.getClassName());
queriesCodegen.addImports(entity.getFullClassName());
queriesCodegen.getConstructor().body.line("super({}.class);", entity.getClassName());
}
private void addDelete(Entity entity, GClass queriesCodegen) {
GMethod delete = queriesCodegen.getMethod("delete").argument(entity.getClassName(), "instance");
for (OneToManyProperty otmp : entity.getOneToManyProperties()) {
if (otmp.isOwnerMe() && !otmp.isManyToMany()) {
if (otmp.isOneToOne()) {
delete.body.line("if (instance.get{}() != null) {", otmp.getCapitalVariableNameSingular());
delete.body.line("_ {}.queries.delete(instance.get{}());", otmp.getTargetJavaType(), otmp.getCapitalVariableNameSingular());
delete.body.line("}");
queriesCodegen.addImports(otmp.getManySide().getFullClassName());
} else {
delete.body.line("for ({} o : Copy.list(instance.get{}())) {", otmp.getTargetJavaType(), otmp.getCapitalVariableName());
delete.body.line("_ {}.queries.delete(o);", otmp.getTargetJavaType());
delete.body.line("}");
queriesCodegen.addImports(otmp.getManySide().getFullClassName(), Copy.class.getName());
}
}
}
for (ManyToOneProperty mtop : entity.getManyToOneProperties()) {
if (mtop.isOwnerMe() && !mtop.getOneSide().isCodeEntity()) {
delete.body.line("if (instance.get{}() != null) {", mtop.getCapitalVariableName());
delete.body.line("_ {}.queries.delete(instance.get{}());", mtop.getJavaType(), mtop.getCapitalVariableName());
delete.body.line("}");
queriesCodegen.addImports(mtop.getOneSide().getFullClassName());
}
}
if (entity.isRoot()) {
delete.body.line("super.delete(instance);");
} else {
delete.body.line("{}.queries.delete(instance);", entity.getBaseEntity().getClassName());
queriesCodegen.addImports(entity.getBaseEntity().getFullClassName());
}
}
private void addFindByForUniquePrimitives(Entity entity, GClass queriesCodegen) {
for (PrimitiveProperty p : entity.getPrimitiveProperties()) {
if (p.isUnique()) {
GMethod findBy = queriesCodegen.getMethod("findBy" + p.getCapitalVariableName(), Argument.arg(p.getJavaType(), p.getVariableName()));
findBy.returnType(entity.getClassName());
findBy.body.line("{} {} = new {}(\"{}\");", entity.getAliasName(), entity.getAliasAlias(), entity.getAliasName(), entity.getAliasAlias());
findBy.body.line(
"return Select.from({}).where({}.{}.eq({})).unique();",
entity.getAliasAlias(),
entity.getAliasAlias(),
p.getVariableName(),
p.getVariableName());
queriesCodegen.addImports(entity.getFullAliasClassName());
queriesCodegen.addImports(Select.class);
}
}
}
private void addFindByForCodes(Entity entity, GClass queriesCodegen) {
for (ManyToOneProperty mtop : entity.getManyToOneProperties()) {
if (mtop.getOneSide().isCodeEntity()) {
GMethod findBy = queriesCodegen.getMethod("findBy" + mtop.getCapitalVariableName(), Argument.arg(mtop.getJavaType(), mtop.getVariableName()));
findBy.returnType("java.util.List<{}>", entity.getClassName());
findBy.body.line("{} {} = new {}();", entity.getAliasName(), entity.getAliasAlias(), entity.getAliasName());
findBy.body.line(
"return Select.from({}).where({}.{}.eq({})).list();",
entity.getAliasAlias(),
entity.getAliasAlias(),
mtop.getVariableName(),
mtop.getVariableName());
GMethod findIdsBy = queriesCodegen.getMethod(
"findIdsBy" + mtop.getCapitalVariableName(),
Argument.arg(mtop.getJavaType(), mtop.getVariableName()));
findIdsBy.returnType("java.util.List<Long>");
findIdsBy.body.line("{} {} = new {}();", entity.getAliasName(), entity.getAliasAlias(), entity.getAliasName());
findIdsBy.body.line(
"return Select.from({}).where({}.{}.eq({})).listIds();",
entity.getAliasAlias(),
entity.getAliasAlias(),
mtop.getVariableName(),
mtop.getVariableName());
queriesCodegen.addImports(entity.getFullAliasClassName(), mtop.getOneSide().getFullClassName());
queriesCodegen.addImports(Select.class);
}
}
}
private void addFindIdForSkippedCollections(Entity entity, GClass queriesCodegen) {
for (OneToManyProperty otmp : entity.getOneToManyProperties()) {
if (otmp.isCollectionSkipped()) {
GMethod findIds = queriesCodegen.getMethod(
"find" + otmp.getCapitalVariableName() + "Ids",
Argument.arg(entity.getClassName(), entity.getVariableName()));
findIds.returnType("java.util.List<Long>");
Entity manySide = otmp.getManySide();
findIds.body.line("{} {} = new {}();", manySide.getAliasName(), manySide.getAliasAlias(), manySide.getAliasName());
findIds.body.line(
"return Select.from({}).where({}.{}.eq({})).listIds();",
manySide.getAliasAlias(),
manySide.getAliasAlias(),
entity.getVariableName(),
entity.getVariableName());
queriesCodegen.addImports(Select.class);
queriesCodegen.addImports(manySide.getFullAliasClassName());
}
}
}
}