mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-09-25 03:31:07 +00:00
#3536 kotlin-querybean-generator update for filterMany() changes
Brings the kotlin-querybean-generator up to date with the [java] querybean-generator in terms of how it has specific "associated beans" for ToOne and ToMany type relationships
This commit is contained in:
+2
-4
@@ -11,6 +11,8 @@ interface Constants {
|
||||
String ENTITY = "jakarta.persistence.Entity";
|
||||
String EMBEDDABLE = "jakarta.persistence.Embeddable";
|
||||
String CONVERTER = "jakarta.persistence.Converter";
|
||||
String ONE_TO_MANY = "jakarta.persistence.OneToMany";
|
||||
String MANY_TO_MANY = "jakarta.persistence.ManyToMany";
|
||||
String EBEAN_COMPONENT = "io.ebean.annotation.EbeanComponent";
|
||||
|
||||
String DBARRAY = "io.ebean.annotation.DbArray";
|
||||
@@ -18,10 +20,6 @@ interface Constants {
|
||||
String DBJSONB = "io.ebean.annotation.DbJsonB";
|
||||
String DBNAME = "io.ebean.annotation.DbName";
|
||||
|
||||
String TQASSOC = "io.ebean.typequery.TQAssoc";
|
||||
String TQASSOCBEAN = "io.ebean.typequery.TQAssocBean";
|
||||
String TQPROPERTY = "io.ebean.typequery.TQProperty";
|
||||
|
||||
String MODULEINFO = "io.ebean.config.ModuleInfo";
|
||||
String METAINF_MANIFEST = "META-INF/ebean-generated-info.mf";
|
||||
String METAINF_SERVICES_MODULELOADER = "META-INF/services/io.ebean.config.EntityClassRegister";
|
||||
|
||||
+14
-64
@@ -1,9 +1,8 @@
|
||||
package io.ebean.querybean.generator;
|
||||
|
||||
class KotlinLangAdapter implements LangAdapter {
|
||||
final class KotlinLangAdapter {
|
||||
|
||||
@Override
|
||||
public void alias(Append writer, String shortName, String fullName) {
|
||||
void alias(Append writer, String shortName, String fullName) {
|
||||
writer.append(" companion object {").eol();
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * shared 'Alias' instance used to provide").eol();
|
||||
@@ -20,87 +19,38 @@ class KotlinLangAdapter implements LangAdapter {
|
||||
writer.append(" }").eol().eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assocBeanConstructor(Append writer, String shortName) {
|
||||
writer.append(" constructor(name: String, root: R) : super(name, root)").eol();
|
||||
writer.eol();
|
||||
writer.append(" constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetch(Append writer, String origShortName) {
|
||||
writeAssocBeanFetch(writer, origShortName, "", "Eagerly fetch this association loading the specified properties.");
|
||||
writeAssocBeanFetch(writer, origShortName, "Query", "Eagerly fetch this association using a 'query join' loading the specified properties.");
|
||||
writeAssocBeanFetch(writer, origShortName, "Cache", "Eagerly fetch this association using L2 cache.");
|
||||
writeAssocBeanFetch(writer, origShortName, "Lazy", "Use lazy loading for this association loading the specified properties.");
|
||||
}
|
||||
|
||||
private void writeAssocBeanFetch(Append writer, String origShortName, String fetchType, String comment) {
|
||||
// fun fetch(vararg properties: TQProperty<QContact,?>): R {
|
||||
// return fetchProperties(*properties)
|
||||
// }
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * ").append(comment).eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" fun fetch%s(vararg properties: TQProperty<Q%s,Any>) : R {", fetchType, origShortName).eol();
|
||||
writer.append(" return fetch%sProperties(*properties)", fetchType).eol();
|
||||
writer.append(" }").eol();
|
||||
writer.eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rootBeanConstructor(Append writer, String shortName, String dbName, String fullName) {
|
||||
void rootBeanConstructor(Append writer, String shortName, String dbName, String fullName) {
|
||||
String name = (dbName == null) ? "default" : dbName;
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * Construct using the %s Database.", name).eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" /** Construct using the %s Database. */", name).eol();
|
||||
if (dbName == null) {
|
||||
writer.append(" constructor() : super(%s::class.java)", fullName).eol().eol();
|
||||
} else {
|
||||
writer.append(" constructor() : super(%s::class.java, io.ebean.DB.byName(\"%s\"))", fullName, dbName).eol().eol();
|
||||
}
|
||||
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * @deprecated migrate to query.usingTransaction()", name).eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" @Deprecated(message=\"migrate to query.usingTransaction()\")").eol();
|
||||
writer.append(" /** @deprecated migrate to query.usingTransaction() */", name).eol();
|
||||
writer.append(" @Deprecated(message=\"migrate to query.usingTransaction()\")").eol();
|
||||
if (dbName == null) {
|
||||
writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, transaction)", fullName).eol().eol();
|
||||
} else {
|
||||
writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, io.ebean.DB.byName(\"%s\"), transaction)", fullName, dbName).eol().eol();
|
||||
}
|
||||
|
||||
writer.eol();
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * Construct with a given Database.").eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" /** Construct with a given Database. */").eol();
|
||||
writer.append(" constructor(database: io.ebean.Database) : super(%s::class.java, database)", fullName).eol().eol();
|
||||
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * Construct for Alias.").eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" /** Construct for Alias. */").eol();
|
||||
writer.append(" private constructor(dummy: Boolean) : super(dummy)").eol().eol();
|
||||
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * Private constructor for FetchGroup building.").eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" private constructor(fetchGroupQuery: io.ebean.Query<%s>) : super(fetchGroupQuery)", fullName).eol();
|
||||
writer.append(" /** Private constructor for FetchGroup building. */").eol();
|
||||
writer.append(" private constructor(fetchGroupQuery: io.ebean.Query<%s>) : super(fetchGroupQuery)", fullName).eol().eol();
|
||||
|
||||
writer.append(" /** Private constructor for filterMany */").eol();
|
||||
writer.append(" private constructor(filter: io.ebean.ExpressionList<%s>) : super(filter)", fullName).eol().eol();
|
||||
|
||||
writer.eol();
|
||||
writer.append(" /** Return a copy of the query. */").eol();
|
||||
writer.append(" override fun copy() : Q%s {", shortName).eol();
|
||||
writer.append(" return Q%s(query().copy())", shortName).eol();
|
||||
writer.append(" }").eol();
|
||||
writer.eol();
|
||||
writer.append(" }").eol().eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fieldDefn(Append writer, String propertyName, String typeDefn) {
|
||||
writer.append(" lateinit var %s: ", propertyName);
|
||||
if (typeDefn.endsWith(",Integer>")) {
|
||||
typeDefn = typeDefn.replace(",Integer>", ",Int>");
|
||||
}
|
||||
writer.append(typeDefn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package io.ebean.querybean.generator;
|
||||
|
||||
public interface LangAdapter {
|
||||
|
||||
|
||||
void alias(Append writer, String shortName, String beanFullName);
|
||||
|
||||
void rootBeanConstructor(Append writer, String shortName, String dbName, String beanFullName);
|
||||
|
||||
void assocBeanConstructor(Append writer, String shortName);
|
||||
|
||||
void fetch(Append writer, String origShortName);
|
||||
|
||||
void fieldDefn(Append writer, String propertyName, String typeDefn);
|
||||
|
||||
}
|
||||
+53
-26
@@ -239,6 +239,10 @@ class ProcessingContext implements Constants {
|
||||
return hasAnnotations(element, EMBEDDABLE);
|
||||
}
|
||||
|
||||
private static boolean dbToMany(Element field) {
|
||||
return hasAnnotations(field, ONE_TO_MANY, MANY_TO_MANY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the DbName annotation and return name if found.
|
||||
*/
|
||||
@@ -261,6 +265,7 @@ class ProcessingContext implements Constants {
|
||||
}
|
||||
|
||||
PropertyType getPropertyType(VariableElement field) {
|
||||
boolean toMany = dbToMany(field);
|
||||
if (dbJsonField(field)) {
|
||||
return propertyTypeMap.getDbJsonType();
|
||||
}
|
||||
@@ -301,36 +306,30 @@ class ProcessingContext implements Constants {
|
||||
if (targetEntity != null) {
|
||||
final TypeElement element = elementUtils.getTypeElement(targetEntity);
|
||||
if (isEntityOrEmbedded(element)) {
|
||||
return createPropertyTypeAssoc(typeDef(element.asType()));
|
||||
boolean embeddable = isEmbeddable(element);
|
||||
return createPropertyTypeAssoc(embeddable, toMany, typeDef(element.asType()));
|
||||
}
|
||||
}
|
||||
if (isEntityOrEmbedded(fieldType)) {
|
||||
// public QAssocContact<QCustomer> contacts;
|
||||
return createPropertyTypeAssoc(typeDef(typeMirror));
|
||||
boolean embeddable = isEmbeddable(fieldType);
|
||||
return createPropertyTypeAssoc(embeddable, toMany, typeDef(typeMirror));
|
||||
}
|
||||
|
||||
final PropertyType result;
|
||||
if (typeMirror.getKind() == TypeKind.DECLARED) {
|
||||
DeclaredType declaredType = (DeclaredType) typeMirror;
|
||||
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
|
||||
if (typeArguments.size() == 1) {
|
||||
TypeMirror argType = typeArguments.get(0);
|
||||
Element argElement = asElement(argType);
|
||||
if (isEntityOrEmbedded(argElement)) {
|
||||
return createPropertyTypeAssoc(typeDef(argElement.asType()));
|
||||
}
|
||||
} else if (typeArguments.size() == 2) {
|
||||
TypeMirror argType = typeArguments.get(1);
|
||||
Element argElement = asElement(argType);
|
||||
if (isEntityOrEmbedded(argElement)) {
|
||||
return createPropertyTypeAssoc(typeDef(argElement.asType()));
|
||||
}
|
||||
}
|
||||
result = createManyTypeAssoc(field, (DeclaredType) typeMirror);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
if (typeInstanceOf(typeMirror, "java.lang.Comparable")) {
|
||||
return new PropertyTypeScalarComparable(trimAnnotations(typeMirror.toString()));
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
return new PropertyTypeScalar(trimAnnotations(typeMirror.toString()));
|
||||
if (typeInstanceOf(typeMirror, "java.lang.Comparable")) {
|
||||
return new PropertyTypeScalarComparable(trimAnnotations(typeMirror.toString()));
|
||||
} else {
|
||||
return new PropertyTypeScalar(trimAnnotations(typeMirror.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +356,25 @@ class ProcessingContext implements Constants {
|
||||
.anyMatch(t -> typeInstanceOf(t, desiredInterface));
|
||||
}
|
||||
|
||||
private PropertyType createManyTypeAssoc(VariableElement field, DeclaredType declaredType) {
|
||||
boolean toMany = dbToMany(field);
|
||||
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
|
||||
if (typeArguments.size() == 1) {
|
||||
Element argElement = typeUtils.asElement(typeArguments.get(0));
|
||||
if (isEntityOrEmbedded(argElement)) {
|
||||
boolean embeddable = isEmbeddable(argElement);
|
||||
return createPropertyTypeAssoc(embeddable, toMany, typeDef(argElement.asType()));
|
||||
}
|
||||
} else if (typeArguments.size() == 2) {
|
||||
Element argElement = typeUtils.asElement(typeArguments.get(1));
|
||||
if (isEntityOrEmbedded(argElement)) {
|
||||
boolean embeddable = isEmbeddable(argElement);
|
||||
return createPropertyTypeAssoc(embeddable, toMany, typeDef(argElement.asType()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String readTargetEntity(Element declaredType) {
|
||||
for (AnnotationMirror annotation : declaredType.getAnnotationMirrors()) {
|
||||
final Object targetEntity = readTargetEntityFromAnnotation(annotation);
|
||||
@@ -386,11 +404,20 @@ class ProcessingContext implements Constants {
|
||||
/**
|
||||
* Create the QAssoc PropertyType.
|
||||
*/
|
||||
private PropertyType createPropertyTypeAssoc(String fullName) {
|
||||
String[] split = Split.split(fullName);
|
||||
String propertyName = "QAssoc" + split[1];
|
||||
String packageName = packageAppend(split[0]);
|
||||
return new PropertyTypeAssoc(propertyName, packageName);
|
||||
private PropertyType createPropertyTypeAssoc(boolean embeddable, boolean toMany, String fullName) {
|
||||
TypeElement typeElement = elementUtils.getTypeElement(fullName);
|
||||
String type;
|
||||
if (typeElement.getNestingKind().isNested()) {
|
||||
type = typeElement.getEnclosingElement().toString() + "$" + typeElement.getSimpleName();
|
||||
} else {
|
||||
type = typeElement.getQualifiedName().toString();
|
||||
}
|
||||
|
||||
String suffix = toMany ? "Many" : embeddable ? "": "One";
|
||||
String[] split = Split.split(type);
|
||||
String propertyName = "Q" + split[1] + ".Assoc" + suffix;
|
||||
String importName = split[0] + ".query.Q" + split[1];
|
||||
return new PropertyTypeAssoc(propertyName, importName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -109,8 +109,7 @@ public class Processor extends AbstractProcessor implements Constants {
|
||||
private void generateQueryBeans(Element element) {
|
||||
try {
|
||||
SimpleQueryBeanWriter beanWriter = new SimpleQueryBeanWriter((TypeElement) element, processingContext);
|
||||
beanWriter.writeRootBean();
|
||||
beanWriter.writeAssocBean();
|
||||
beanWriter.writeBean();
|
||||
} catch (Throwable e) {
|
||||
processingContext.logError(element, "Error generating query beans: " + e);
|
||||
}
|
||||
|
||||
+4
-13
@@ -7,25 +7,16 @@ import java.util.Set;
|
||||
*/
|
||||
class PropertyTypeAssoc extends PropertyType {
|
||||
|
||||
/**
|
||||
* The package name for this associated query bean.
|
||||
*/
|
||||
private final String assocPackage;
|
||||
private final String importName;
|
||||
|
||||
/**
|
||||
* Construct given the associated bean type name and package.
|
||||
*
|
||||
* @param qAssocTypeName the associated bean type name.
|
||||
* @param assocPackage the associated bean package.
|
||||
*/
|
||||
PropertyTypeAssoc(String qAssocTypeName, String assocPackage) {
|
||||
PropertyTypeAssoc(String qAssocTypeName, String importName) {
|
||||
super(qAssocTypeName);
|
||||
this.assocPackage = assocPackage;
|
||||
this.importName = importName;
|
||||
}
|
||||
|
||||
@Override
|
||||
void addImports(Set<String> allImports) {
|
||||
allImports.add(assocPackage + "." + propertyType);
|
||||
allImports.add(importName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+87
-123
@@ -12,7 +12,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
@@ -74,19 +73,17 @@ class SimpleQueryBeanWriter {
|
||||
private final boolean embeddable;
|
||||
private final String dbName;
|
||||
private final String beanFullName;
|
||||
private final LangAdapter langAdapter;
|
||||
private boolean writingAssocBean;
|
||||
private final KotlinLangAdapter langAdapter = new KotlinLangAdapter();
|
||||
private boolean writingEmbeddedBean;
|
||||
private final String generatedSourcesDir;
|
||||
|
||||
private String destPackage;
|
||||
private String origDestPackage;
|
||||
private String shortName;
|
||||
private final String shortInnerName;
|
||||
private final String origShortName;
|
||||
private Append writer;
|
||||
|
||||
SimpleQueryBeanWriter(TypeElement element, ProcessingContext processingContext) {
|
||||
this.langAdapter = new KotlinLangAdapter();
|
||||
this.generatedSourcesDir = processingContext.generatedSourcesDir();
|
||||
this.element = element;
|
||||
this.processingContext = processingContext;
|
||||
@@ -95,7 +92,7 @@ class SimpleQueryBeanWriter {
|
||||
this.destPackage = Util.packageOf(nested, beanFullName) + ".query";
|
||||
String sn = Util.shortName(nested, beanFullName);
|
||||
this.shortInnerName = Util.shortName(false, sn);
|
||||
this.shortName = sn.replace(".", "");
|
||||
this.shortName = sn.replace(".", "_"); // $ not supported with Kotlin, see kotlinInnerType()
|
||||
this.origShortName = shortName;
|
||||
this.isEntity = processingContext.isEntity(element);
|
||||
this.embeddable = processingContext.isEmbeddable(element);
|
||||
@@ -118,8 +115,8 @@ class SimpleQueryBeanWriter {
|
||||
return processingContext.findDbName(element);
|
||||
}
|
||||
|
||||
private LangAdapter lang() {
|
||||
return langAdapter;
|
||||
private static String kotlinInnerType(String fullType) {
|
||||
return fullType.replace('$', '_');
|
||||
}
|
||||
|
||||
private void gatherPropertyDetails() {
|
||||
@@ -148,25 +145,24 @@ class SimpleQueryBeanWriter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the type query bean (root bean).
|
||||
* Write the type query bean.
|
||||
*/
|
||||
void writeRootBean() throws IOException {
|
||||
void writeBean() throws IOException {
|
||||
gatherPropertyDetails();
|
||||
translateKotlinImportTypes();
|
||||
if (isEmbeddable()) {
|
||||
processingContext.addEntity(beanFullName, dbName);
|
||||
writeEmbeddedBean();
|
||||
} else if (isEntity()) {
|
||||
processingContext.addEntity(beanFullName, dbName);
|
||||
writer = new Append(createFileWriter());
|
||||
|
||||
translateKotlinImportTypes();
|
||||
|
||||
writePackage();
|
||||
writeImports();
|
||||
writeClass();
|
||||
writeAlias();
|
||||
writeFields();
|
||||
writeFields(false);
|
||||
writeConstructors();
|
||||
//writeStaticAliasClass();
|
||||
writeClassEnd();
|
||||
|
||||
writer.close();
|
||||
@@ -196,139 +192,53 @@ class SimpleQueryBeanWriter {
|
||||
/**
|
||||
* Write the type query assoc bean.
|
||||
*/
|
||||
void writeAssocBean() throws IOException {
|
||||
writingAssocBean = true;
|
||||
origDestPackage = destPackage;
|
||||
destPackage = destPackage + ".assoc";
|
||||
shortName = "Assoc" + shortName;
|
||||
void writeEmbeddedBean() throws IOException {
|
||||
writingEmbeddedBean = true;
|
||||
|
||||
prepareAssocBeanImports();
|
||||
writer = new Append(createFileWriter());
|
||||
|
||||
writePackage();
|
||||
writeImports();
|
||||
writeClass();
|
||||
writeFields();
|
||||
writeConstructors();
|
||||
writeEmbeddedAssoc();
|
||||
writeClassEnd();
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the imports for writing assoc bean.
|
||||
*/
|
||||
private void prepareAssocBeanImports() {
|
||||
if (embeddable) {
|
||||
importTypes.add(Constants.TQASSOC);
|
||||
} else {
|
||||
importTypes.add(Constants.TQASSOCBEAN);
|
||||
}
|
||||
if (isEntity()) {
|
||||
importTypes.add(Constants.TQPROPERTY);
|
||||
importTypes.add(origDestPackage + ".Q" + origShortName);
|
||||
//if (implementsInterface != null) {
|
||||
// importTypes.add(Constants.AVAJE_LANG_NULLABLE);
|
||||
// importTypes.add(Constants.JAVA_COLLECTION);
|
||||
// importTypes.add(implementsInterfaceFullName);
|
||||
//}
|
||||
}
|
||||
|
||||
// remove imports for the same package
|
||||
Iterator<String> importsIterator = importTypes.iterator();
|
||||
String checkImportStart = destPackage + ".QAssoc";
|
||||
while (importsIterator.hasNext()) {
|
||||
String importType = importsIterator.next();
|
||||
if (importType.startsWith(checkImportStart)) {
|
||||
importsIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write constructors.
|
||||
*/
|
||||
private void writeConstructors() {
|
||||
if (writingAssocBean) {
|
||||
writeAssocBeanFetch();
|
||||
writeAssocBeanConstructor();
|
||||
} else {
|
||||
writeRootBeanConstructor();
|
||||
}
|
||||
langAdapter.rootBeanConstructor(writer, shortName, dbName, beanFullName);
|
||||
writeAssocClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constructors for 'root' type query bean.
|
||||
*/
|
||||
private void writeRootBeanConstructor() {
|
||||
lang().rootBeanConstructor(writer, shortName, dbName, beanFullName);
|
||||
}
|
||||
|
||||
private void writeAssocBeanFetch() {
|
||||
if (isEntity()) {
|
||||
//if (implementsInterface != null) {
|
||||
// writeAssocBeanExpression(false, "eq", "Is equal to by ID property.");
|
||||
// writeAssocBeanExpression(true, "eqIfPresent", "Is equal to by ID property if the value is not null, if null no expression is added.");
|
||||
// writeAssocBeanExpression(false, "in", "IN the given values.", implementsInterfaceShortName + "...", "in");
|
||||
// writeAssocBeanExpression(false, "inBy", "IN the given interface values.", "Collection<" + implementsInterfaceShortName + ">", "in");
|
||||
// writeAssocBeanExpression(true, "inOrEmptyBy", "IN the given interface values if the collection is not empty. No expression is added if the collection is empty..", "Collection<" + implementsInterfaceShortName + ">", "inOrEmpty");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAssocBeanExpression(boolean nullable,String expression, String comment) {
|
||||
writeAssocBeanExpression(nullable, expression, comment, implementsInterfaceShortName, expression);
|
||||
}
|
||||
|
||||
private void writeAssocBeanExpression(boolean nullable, String expression, String comment, String param, String actualExpression) {
|
||||
final String nullableAnnotation = nullable ? "@Nullable " : "";
|
||||
String values = expression.startsWith("in") ? "values" : "value";
|
||||
writer.append(" /**").eol();
|
||||
writer.append(" * ").append(comment).eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(" fun %s(%s%s %s): R {", expression, nullableAnnotation, param, values).eol();
|
||||
writer.append(" expr().%s(_name, %s);", actualExpression, values).eol();
|
||||
writer.append(" return _root;").eol();
|
||||
writer.append(" }").eol();
|
||||
writer.eol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write constructor for 'assoc' type query bean.
|
||||
*/
|
||||
private void writeAssocBeanConstructor() {
|
||||
lang().assocBeanConstructor(writer, shortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all the fields.
|
||||
*/
|
||||
private void writeFields() {
|
||||
private void writeFields(boolean assocBeans) {
|
||||
String padding = assocBeans ? " " : "";
|
||||
for (PropertyMeta property : properties) {
|
||||
String typeDefn = property.getTypeDefn(shortName, writingAssocBean);
|
||||
lang().fieldDefn(writer, property.getName(), typeDefn);
|
||||
writer.eol();
|
||||
String typeDefn = kotlinTypeDefn(property.getTypeDefn(shortName, assocBeans));
|
||||
writer.append("%s lateinit var %s: %s", padding, property.getName(), kotlinInnerType(typeDefn)).eol();
|
||||
}
|
||||
writer.eol();
|
||||
}
|
||||
|
||||
private static String kotlinTypeDefn(String type) {
|
||||
if (type.endsWith(",Integer>")) {
|
||||
return type.replace(",Integer>", ",Int>");
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the class definition.
|
||||
*/
|
||||
private void writeClass() {
|
||||
if (writingAssocBean) {
|
||||
if (writingEmbeddedBean) {
|
||||
writer.append("/**").eol();
|
||||
writer.append(" * Association query bean for %s.", shortName).eol();
|
||||
writer.append(" * ").eol();
|
||||
writer.append(" * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.").eol();
|
||||
writer.append(" */").eol();
|
||||
writer.append(Constants.AT_GENERATED).eol();
|
||||
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
||||
if (embeddable) {
|
||||
writer.append("class Q%s<R> : TQAssoc<%s,R> {", shortName, beanFullName).eol();
|
||||
} else {
|
||||
writer.append("class Q%s<R> : TQAssocBean<%s,R,Q%s> {", shortName, beanFullName, origShortName).eol();
|
||||
}
|
||||
writer.append("class Q%s {", shortName).eol();
|
||||
} else {
|
||||
writer.append("/**").eol();
|
||||
writer.append(" * Query bean for %s.", shortName).eol();
|
||||
@@ -344,9 +254,7 @@ class SimpleQueryBeanWriter {
|
||||
}
|
||||
|
||||
private void writeAlias() {
|
||||
if (!writingAssocBean) {
|
||||
lang().alias(writer, shortName, beanFullName);
|
||||
}
|
||||
langAdapter.alias(writer, shortName, beanFullName);
|
||||
}
|
||||
|
||||
private void writeClassEnd() {
|
||||
@@ -358,7 +266,7 @@ class SimpleQueryBeanWriter {
|
||||
*/
|
||||
private void writeImports() {
|
||||
for (String importType : importTypes) {
|
||||
writer.append("import %s;", importType).eol();
|
||||
writer.append("import %s;", kotlinInnerType(importType)).eol();
|
||||
}
|
||||
writer.eol();
|
||||
}
|
||||
@@ -379,4 +287,60 @@ class SimpleQueryBeanWriter {
|
||||
return new FileWriter(absFile);
|
||||
}
|
||||
|
||||
private void writeEmbeddedAssoc() {
|
||||
writer.append(" @io.ebean.typequery.Generated(\"io.ebean.querybean.generator\") @io.ebean.typequery.TypeQueryBean(\"v1\")").eol();
|
||||
writer.append(" class Assoc<R> : io.ebean.typequery.TQAssoc<%s,R> {", beanFullName).eol().eol();
|
||||
writeFields(true);
|
||||
writer.append(" protected constructor(name: String, root: R) : super(name, root)").eol();
|
||||
writer.append(" protected constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
}
|
||||
|
||||
private void writeAssocClasses() {
|
||||
writer.append(" @io.ebean.typequery.Generated(\"io.ebean.querybean.generator\") @io.ebean.typequery.TypeQueryBean(\"v1\")").eol();
|
||||
writer.append(" abstract class Assoc<R> : io.ebean.typequery.TQAssocBean<%s, R, Q%s> {", beanFullName, shortName).eol();
|
||||
|
||||
writeFields(true);
|
||||
writer.append(" protected constructor(name: String, root: R) : super(name, root)").eol();
|
||||
writer.append(" protected constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
|
||||
writer.append(" @io.ebean.typequery.Generated(\"io.ebean.querybean.generator\") @io.ebean.typequery.TypeQueryBean(\"v1\")").eol();
|
||||
writer.append(" class AssocOne<R> : Assoc<R> {").eol();
|
||||
writer.append(" constructor(name: String, root: R) : super(name, root)").eol();
|
||||
writer.append(" constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
|
||||
writer.append(" @io.ebean.typequery.Generated(\"io.ebean.querybean.generator\") @io.ebean.typequery.TypeQueryBean(\"v1\")").eol();
|
||||
writer.append(" class AssocMany<R> : Assoc<R>, io.ebean.typequery.TQAssocMany<%s, R, Q%s> {", beanFullName, shortName).eol();
|
||||
writer.append(" constructor(name: String, root: R) : super(name, root)").eol();
|
||||
writer.append(" constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
|
||||
writer.eol();
|
||||
writer.append(" override fun filterMany(apply: java.util.function.Consumer<Q%s>): R {", shortName).eol();
|
||||
writer.append(" val list: io.ebean.ExpressionList<%s> = _newExpressionList<%s>()", beanFullName, beanFullName).eol();
|
||||
writer.append(" apply.accept(Q%s(list))", shortName).eol();
|
||||
writer.append(" return _filterMany(list)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
writer.append(" override fun filterMany(filter: io.ebean.ExpressionList<%s>): R {", beanFullName).eol();
|
||||
writer.append(" return _filterMany(filter)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
writer.append(" override fun filterManyRaw(rawExpressions: String, vararg params: Any): R {").eol();
|
||||
writer.append(" return _filterManyRaw(rawExpressions, *params)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
|
||||
// Ebean 14.x only
|
||||
writer.append(" @Deprecated(\"for removal, migrate to filterManyRaw()\")").eol();
|
||||
writer.append(" override fun filterMany(rawExpressions: String, vararg params: Any): R {").eol();
|
||||
writer.append(" return _filterMany(rawExpressions, *params)").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
|
||||
writer.append(" override fun isEmpty(): R {").eol();
|
||||
writer.append(" return _isEmpty() ").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
writer.append(" override fun isNotEmpty(): R {").eol();
|
||||
writer.append(" return _isNotEmpty() ").eol();
|
||||
writer.append(" }").eol().eol();
|
||||
|
||||
writer.append(" }").eol();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<!-- <artifactId>querybean-generator</artifactId>-->
|
||||
<version>14.8.0</version>
|
||||
<version>14.8.1</version>
|
||||
</annotationProcessorPath>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.example.domain
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_inner2")
|
||||
class MyKInnerEmb {
|
||||
|
||||
@Id
|
||||
var one: Long = 0
|
||||
var two: String = "0"
|
||||
var address: EmbAddre? = null
|
||||
|
||||
@Embeddable
|
||||
data class EmbAddre(val line1: String, val line2: String)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user