[#2155] [#3624] Add Converter support to Routines and UDTs

- Updated API and code generator to fix compilation issues
- Integration tests not yet implemented
This commit is contained in:
Lukas Eder 2014-09-05 17:05:49 +02:00
parent dbd2497441
commit 0877a37084
6 changed files with 135 additions and 22 deletions

View File

@ -1075,10 +1075,18 @@ public class JavaGenerator extends AbstractGenerator {
final String attrId = getStrategy().getJavaIdentifier(attribute);
final String attrName = attribute.getName();
final String attrComment = StringUtils.defaultString(attribute.getComment());
final String attrConverterType = attribute.getType().getConverter();
out.tab(1).javadoc("The attribute <code>%s</code>.%s", attribute.getQualifiedOutputName(), defaultIfBlank(" " + attrComment, ""));
out.tab(1).println("public static final %s<%s, %s> %s = createField(\"%s\", %s, %s);",
UDTField.class, recordType, attrType, attrId, attrName, attrTypeRef, udtId);
if (attrConverterType != null) {
out.tab(1).println("public static final %s<%s, %s> %s = createField(\"%s\", %s, %s, \"%s\", new %s());",
UDTField.class, recordType, attrType, attrId, attrName, attrTypeRef, udtId, escapeString(""), attrConverterType);
}
else {
out.tab(1).println("public static final %s<%s, %s> %s = createField(\"%s\", %s, %s, \"%s\");",
UDTField.class, recordType, attrType, attrId, attrName, attrTypeRef, udtId, escapeString(""));
}
}
// [#799] Oracle UDT's can have member procedures
@ -1295,6 +1303,7 @@ public class JavaGenerator extends AbstractGenerator {
xxxxx xxxxxxxxxxxx xxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
xxxxx xxxxxx xxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxx
xxxxx xxxxxx xxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxx xxxxxx xxxxxxxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxx xxx x xxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxx
@ -1308,7 +1317,12 @@ public class JavaGenerator extends AbstractGenerator {
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x xxxxx x xxxxxxx x xxx xxx xxxxxx xxxxxx xxxxxxxxxxx xxxxxxxxx xxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxxxxxxxxxx xxx xxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxx
xx xxxxxxxxxxxxxxxxxxxxx xx xxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx
xxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x xxxxx x xxxxxxx x xxx xxx xxxxxx xxxxxx xxxxxxxxxxx xxxxxxxxx xxxxxxxxxxx
@ -1328,7 +1342,12 @@ public class JavaGenerator extends AbstractGenerator {
xxxxxxxxxxxxxxxxxxxxxxxxxx x xxx xxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx xxxx xxx xxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxx
xx xxxxxxxxxxxxxxxxxxxxx xx xxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx
xxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxx xxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx x xxx xxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@ -2543,6 +2562,9 @@ public class JavaGenerator extends AbstractGenerator {
final List<?> returnTypeRef = list((routine.getReturnValue() != null)
? getJavaTypeReference(database, routine.getReturnType())
: null);
final List<?> returnConverterType = list((routine.getReturnValue() != null)
? routine.getReturnType().getConverter()
: null);
final List<String> interfaces = getStrategy().getJavaClassImplements(routine, Mode.DEFAULT);
final String schemaId = getStrategy().getFullJavaIdentifier(schema);
final List<String> packageId = getStrategy().getFullJavaIdentifiers(routine.getPackage());
@ -2561,16 +2583,22 @@ public class JavaGenerator extends AbstractGenerator {
final String paramId = getStrategy().getJavaIdentifier(parameter);
final String paramName = parameter.getName();
final String paramComment = StringUtils.defaultString(parameter.getComment());
final List<String> isDefaulted = list(parameter.isDefaulted() ? "true" : null);
final String isDefaulted = parameter.isDefaulted() ? "true" : "false";
final String paramConverterType = parameter.getType().getConverter();
out.tab(1).javadoc("The parameter <code>%s</code>.%s", parameter.getQualifiedOutputName(), defaultIfBlank(" " + paramComment, ""));
out.tab(1).println("public static final %s<%s> %s = createParameter(\"%s\", %s[[before=, ][%s]]);",
Parameter.class, paramType, paramId, paramName, paramTypeRef, isDefaulted);
if (paramConverterType != null)
out.tab(2).println("public static final %s<%s> %s = createParameter(\"%s\", %s, %s, new %s());",
Parameter.class, paramType, paramId, paramName, paramTypeRef, isDefaulted, paramConverterType);
else
out.tab(2).println("public static final %s<%s> %s = createParameter(\"%s\", %s, %s);",
Parameter.class, paramType, paramId, paramName, paramTypeRef, isDefaulted);
}
out.tab(1).javadoc("Create a new routine call instance");
out.tab(1).println("public %s() {", className);
out.tab(2).println("super(\"%s\", %s[[before=, ][%s]][[before=, ][%s]]);", routine.getName(), schemaId, packageId, returnTypeRef);
out.tab(2).println("super(\"%s\", %s[[before=, ][%s]][[before=, ][%s]][[before=, ][new %s()]]);", routine.getName(), schemaId, packageId, returnTypeRef, returnConverterType);
if (routine.getAllParameters().size() > 0) {
out.println();

View File

@ -73,6 +73,7 @@ import org.jooq.BindContext;
import org.jooq.Clause;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DSLContext;
import org.jooq.DataType;
import org.jooq.ExecuteContext;
@ -137,18 +138,27 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
// ------------------------------------------------------------------------
protected AbstractRoutine(String name, Schema schema) {
this(name, schema, null, null);
this(name, schema, null, null, null);
}
protected AbstractRoutine(String name, Schema schema, Package pkg) {
this(name, schema, pkg, null);
this(name, schema, pkg, null, null);
}
protected AbstractRoutine(String name, Schema schema, DataType<T> type) {
this(name, schema, null, type);
this(name, schema, null, type, null);
}
protected AbstractRoutine(String name, Schema schema, DataType<?> type, Converter<?, T> converter) {
this(name, schema, null, type, converter);
}
protected AbstractRoutine(String name, Schema schema, Package pkg, DataType<T> type) {
this(name, schema, pkg, type, null);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected AbstractRoutine(String name, Schema schema, Package pkg, DataType<?> type, Converter<?, T> converter) {
this.parameterIndexes = new HashMap<Parameter<?>, Integer>();
this.schema = schema;
@ -161,7 +171,9 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
this.inValuesDefaulted = new HashSet<Parameter<?>>();
this.inValuesNonDefaulted = new HashSet<Parameter<?>>();
this.results = new HashMap<Parameter<?>, Object>();
this.type = type;
this.type = converter == null
? (DataType<T>) type
: type.asConvertedDataType((Converter) converter);
}
// ------------------------------------------------------------------------
@ -752,7 +764,7 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
* @param type The data type of the field
*/
protected static final <T> Parameter<T> createParameter(String name, DataType<T> type) {
return createParameter(name, type, false);
return createParameter(name, type, false, null);
}
/**
@ -765,7 +777,20 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
* {@link Parameter#isDefaulted()}
*/
protected static final <T> Parameter<T> createParameter(String name, DataType<T> type, boolean isDefaulted) {
return new ParameterImpl<T>(name, type, isDefaulted);
return createParameter(name, type, isDefaulted, null);
}
/**
* Subclasses may call this method to create {@link UDTField} objects that
* are linked to this table.
*
* @param name The name of the field (case-sensitive!)
* @param type The data type of the field
* @param isDefaulted Whether the parameter is defaulted (see
* {@link Parameter#isDefaulted()}
*/
protected static final <T, U> Parameter<U> createParameter(String name, DataType<T> type, boolean isDefaulted, Converter<T, U> converter) {
return new ParameterImpl<U>(name, type, isDefaulted, converter);
}
/**

View File

@ -54,6 +54,7 @@ xxxxxx xxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxxxx
xxxxxx xxxxxxxxxxxxxxxx
@ -81,6 +82,8 @@ xxxxxx xxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxx
x xxxxxx xx xxxxx xxxxx xxxxxx
x
x xxxxxxxxxxx x xxxxx x xxxxxxx x xxx xxx
x xxxxxx xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxxx
x xxxxxxxxxxx xxxxxxx
xx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxx
@ -88,19 +91,41 @@ xxxxxx xxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxx
xxxxxxxxxxxx xxxxx xxxxxx
x
xxx
x xxxxxx xx xxxxx xxxxx xxxxxx
x
x xxxxxxxxxxx x xxxxx x xxxxxxx x xxx xxx
x xxxxxx xxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxx xxxxxxxxxxx
x xxxxxxxxxxx xxxxxxxx
xx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxx
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxx xxxxx xxxxxxxxxxx xxxxx xxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxx xx xxxxxxxxxx x
xxxxxxxxxxxx xxxxx xxxxx xxxxxxxxxxx
x
xxx
x xxxxxx xx xxxxx xxxxx xxxxxx
xx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxx xxxxx xxxxxxxxxxx xxxxx x
xxxxxxxxxxxx xxxxx xxxxx xxxxxxxxxxxxx xxx xxxxxx
x
xxx
x xxxxxx xx xxxxx xxxxx xxxxxx
xx
xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx xxxxxxxxxx xx
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxx xxxxx xxxxxxxxxxx xxxxx xxxxxxxxxxxx xx xxxxxxxxxx x
xxxxxxxxxxxx
xxxxxxxxxxx x xxxxxxx
xxxxxxxxx x xxxxx
xxxxxxxxxxxxx x xxxxx
xxxxxxxxxxxxx x xxxxxxxxx xx xxxx
x xxxxxxxxxxxxx xxxx
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxx
xx xxxxx xxxx xxxx xxxxxxxxxxxxxx
xxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x
xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

View File

@ -44,6 +44,7 @@ package org.jooq.impl;
import org.jooq.Clause;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.Parameter;
import org.jooq.tools.StringUtils;
@ -61,10 +62,13 @@ class ParameterImpl<T> extends AbstractQueryPart implements Parameter<T> {
private final DataType<T> type;
private final boolean isDefaulted;
ParameterImpl(String name, DataType<T> type, boolean isDefaulted) {
@SuppressWarnings({ "unchecked", "rawtypes" })
ParameterImpl(String name, DataType<?> type, boolean isDefaulted, Converter<?, T> converter) {
this.name = name;
this.type = type;
this.isDefaulted = isDefaulted;
this.type = converter == null
? (DataType<T>) type
: type.asConvertedDataType((Converter) converter);
}
@Override

View File

@ -42,6 +42,7 @@
package org.jooq.impl;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.UDT;
import org.jooq.UDTField;
@ -58,8 +59,8 @@ class UDTFieldImpl<R extends UDTRecord<R>, T> extends AbstractField<T> implement
private final UDT<R> udt;
UDTFieldImpl(String name, DataType<T> type, UDT<R> udt) {
super(name, type);
UDTFieldImpl(String name, DataType<T> type, UDT<R> udt, String comment, Converter<?, T> converter) {
super(name, type, comment, converter);
this.udt = udt;

View File

@ -42,6 +42,7 @@ package org.jooq.impl;
import org.jooq.Clause;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Record;
@ -156,7 +157,36 @@ public class UDTImpl<R extends UDTRecord<R>> extends AbstractQueryPart implement
* @param type The data type of the field
*/
protected static final <R extends UDTRecord<R>, T> UDTField<R, T> createField(String name, DataType<T> type, UDT<R> udt) {
return new UDTFieldImpl<R, T>(name, type, udt);
return createField(name, type, udt, "", null);
}
/**
* Subclasses may call this method to create {@link UDTField} objects that
* are linked to this table.
*
* @param name The name of the field (case-sensitive!)
* @param type The data type of the field
*/
protected static final <R extends UDTRecord<R>, T> UDTField<R, T> createField(String name, DataType<T> type, UDT<R> udt, String comment) {
return createField(name, type, udt, comment, null);
}
/**
* Subclasses may call this method to create {@link UDTField} objects that
* are linked to this table.
*
* @param name The name of the field (case-sensitive!)
* @param type The data type of the field
*/
@SuppressWarnings("unchecked")
protected static final <R extends UDTRecord<R>, T, U> UDTField<R, U> createField(String name, DataType<T> type, UDT<R> udt, String comment, Converter<T, U> converter) {
final DataType<U> actualType = converter == null
? (DataType<U>) type
: type.asConvertedDataType(converter);
final UDTFieldImpl<R, U> udtField = new UDTFieldImpl<R, U>(name, actualType, udt, comment, converter);
return udtField;
}
// ------------------------------------------------------------------------