diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGenerator.java index 83a9a57a9c..dc765f243e 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGenerator.java @@ -928,7 +928,7 @@ public class DefaultGenerator implements Generator { // XXX Generating UDTs // ---------------------------------------------------------------------- - File targetUDTPackageDir = new File(targetPackageDir, "udt"); + File targetUDTPackageDir = new File(targetPackageDir, "udt"); if (database.getUDTs().size() > 0) { log.info("Generating UDTs", targetUDTPackageDir.getCanonicalPath()); @@ -948,7 +948,16 @@ public class DefaultGenerator implements Generator { out.print(UDTImpl.class); out.print("<"); out.print(strategy.getFullJavaClassName(udt, "Record")); - out.println("> {"); + out.print(">"); + + // [#799] Oracle UDTs with member procedures have similarities + // with packages + if (udt.getRoutines().size() > 0) { + out.print(" implements "); + out.print(org.jooq.Package.class); + } + + out.println(" {"); out.printSerial(); printSingletonInstance(udt, out); @@ -958,6 +967,29 @@ public class DefaultGenerator implements Generator { printUDTColumn(out, attribute, udt); } + // [#799] Oracle UDT's can have member procedures + for (RoutineDefinition routine : udt.getRoutines()) { + try { + if (!routine.isSQLUsable()) { + + // Static execute() convenience method + printConvenienceMethodProcedure(out, routine, false); + } + else { + + // Static execute() convenience method + printConvenienceMethodFunction(out, routine, false); + + // Static asField() convenience method + printConvenienceMethodFunctionAsField(out, routine, false); + printConvenienceMethodFunctionAsField(out, routine, true); + } + + } catch (Exception e) { + log.error("Error while generating routine " + routine, e); + } + } + out.println(); printNoFurtherInstancesAllowedJavadoc(out); out.println("\tprivate " + strategy.getJavaClassName(udt) + "() {"); @@ -990,7 +1022,7 @@ public class DefaultGenerator implements Generator { // ---------------------------------------------------------------------- // XXX Generating UDT record classes // ---------------------------------------------------------------------- - File targetRecordUDTPackageDir = new File(new File(targetPackageDir, "udt"), "records"); + File targetRecordUDTPackageDir = new File(targetUDTPackageDir, "records"); if (database.getUDTs().size() > 0) { log.info("Generating UDT records", targetRecordUDTPackageDir.getCanonicalPath()); @@ -1019,6 +1051,23 @@ public class DefaultGenerator implements Generator { printGetterAndSetter(out, attribute); } + // [#799] Oracle UDT's can have member procedures + for (RoutineDefinition routine : udt.getRoutines()) { + try { + if (!routine.isSQLUsable()) { + // Instance execute() convenience method + printConvenienceMethodProcedure(out, routine, true); + } + else { + // Instance execute() convenience method + printConvenienceMethodFunction(out, routine, true); + } + + } catch (Exception e) { + log.error("Error while generating routine " + routine, e); + } + } + out.println(); out.println("\tpublic " + strategy.getJavaClassName(udt, "Record") + "() {"); @@ -1037,10 +1086,36 @@ public class DefaultGenerator implements Generator { watch.splitInfo("UDT records generated"); } + // ---------------------------------------------------------------------- + // XXX Generating UDT member procedures + // ---------------------------------------------------------------------- + if (database.getUDTs().size() > 0) { + for (UDTDefinition udt : database.getUDTs()) { + if (udt.getRoutines().size() > 0) { + try { + File dir = new File(targetUDTPackageDir, strategy.getJavaIdentifierUC(udt).toLowerCase()); + log.info("Generating member routines", dir.getCanonicalPath()); + + for (RoutineDefinition routine : udt.getRoutines()) { + try { + printRoutine(database, schema, routine); + } catch (Exception e) { + log.error("Error while generating member routines " + routine, e); + } + } + } catch (Exception e) { + log.error("Error while generating UDT " + udt, e); + } + + watch.splitInfo("Member procedures routines"); + } + } + } + // ---------------------------------------------------------------------- // XXX Generating ARRAY record classes // ---------------------------------------------------------------------- - File targetRecordARRAYPackageDir = new File(new File(targetPackageDir, "udt"), "records"); + File targetRecordARRAYPackageDir = new File(targetUDTPackageDir, "records"); if (database.getArrays().size() > 0) { log.info("Generating ARRAYs", targetRecordARRAYPackageDir.getCanonicalPath()); @@ -1193,12 +1268,12 @@ public class DefaultGenerator implements Generator { if (!routine.isSQLUsable()) { // Static execute() convenience method - printConvenienceMethodProcedure(outR, routine); + printConvenienceMethodProcedure(outR, routine, false); } else { // Static execute() convenience method - printConvenienceMethodFunction(outR, routine); + printConvenienceMethodFunction(outR, routine, false); // Static asField() convenience method printConvenienceMethodFunctionAsField(outR, routine, false); @@ -1225,7 +1300,7 @@ public class DefaultGenerator implements Generator { for (PackageDefinition pkg : database.getPackages()) { try { - File targetPackagePackageDir = new File(targetPackagesPackageDir, strategy.getJavaClassName(pkg).toLowerCase()); + File targetPackagePackageDir = new File(targetPackagesPackageDir, strategy.getJavaIdentifierUC(pkg).toLowerCase()); log.info("Generating package", targetPackagePackageDir.getCanonicalPath()); for (RoutineDefinition routine : pkg.getRoutines()) { @@ -1263,11 +1338,11 @@ public class DefaultGenerator implements Generator { try { if (!routine.isSQLUsable()) { // Static execute() convenience method - printConvenienceMethodProcedure(outPkg, routine); + printConvenienceMethodProcedure(outPkg, routine, false); } else { // Static execute() convenience method - printConvenienceMethodFunction(outPkg, routine); + printConvenienceMethodFunction(outPkg, routine, false); // Static asField() convenience method printConvenienceMethodFunctionAsField(outPkg, routine, false); @@ -1384,6 +1459,7 @@ public class DefaultGenerator implements Generator { } out.print(">"); + out.println(" {"); out.printSerial(); out.println(); @@ -1588,7 +1664,7 @@ public class DefaultGenerator implements Generator { out.println("\t}"); } - private void printConvenienceMethodFunction(GenerationWriter out, RoutineDefinition function) throws SQLException { + private void printConvenienceMethodFunction(GenerationWriter out, RoutineDefinition function, boolean instance) throws SQLException { // [#281] - Java can't handle more than 255 method parameters if (function.getInParameters().size() > 254) { log.warn("Too many parameters", "Function " + function + " has more than 254 in parameters. Skipping generation of convenience method."); @@ -1606,20 +1682,36 @@ public class DefaultGenerator implements Generator { printThrowsDataAccessException(out); out.println("\t */"); + out.print("\tpublic "); + + if (!instance) { + out.print("static "); + } - out.print("\tpublic static "); out.print(getJavaType(function.getReturnType())); out.print(" "); out.print(strategy.getJavaClassNameLC(function)); out.print("("); - out.print(Configuration.class); - out.print(" configuration"); + + String glue = ""; + if (!instance) { + out.print(Configuration.class); + out.print(" configuration"); + glue = ", "; + } for (ParameterDefinition parameter : function.getInParameters()) { - out.print(", "); + // Skip SELF parameter + if (instance && parameter.equals(function.getInParameters().get(0))) { + continue; + } + + out.print(glue); printNumberType(out, parameter.getType()); out.print(" "); out.print(strategy.getJavaClassNameLC(parameter)); + + glue = ", "; } out.println(") {"); @@ -1630,12 +1722,35 @@ public class DefaultGenerator implements Generator { out.println("();"); for (ParameterDefinition parameter : function.getInParameters()) { - out.println("\t\tf.set" + strategy.getJavaClassName(parameter) + "(" + strategy.getJavaClassNameLC(parameter) + ");"); + out.print("\t\tf.set"); + out.print(strategy.getJavaClassName(parameter)); + out.print("("); + + if (instance && parameter.equals(function.getInParameters().get(0))) { + out.print("this"); + } + else { + out.print(strategy.getJavaClassNameLC(parameter)); + } + + out.println(");"); } out.println(); + out.print("\t\tf.execute("); + + if (instance) { + out.print("getConfiguration()"); + } + else { + out.print("configuration"); + } + + out.println(");"); + + // TODO [#956] Find a way to register "SELF" as OUT parameter + // in case this is a UDT instance (member) function - out.println("\t\tf.execute(configuration);"); out.println("\t\treturn f.getReturnValue();"); out.println("\t}"); } @@ -1655,7 +1770,7 @@ public class DefaultGenerator implements Generator { out.println("\tprivate " + javaClassName + "() {}"); } - private void printConvenienceMethodProcedure(GenerationWriter out, RoutineDefinition procedure) throws SQLException { + private void printConvenienceMethodProcedure(GenerationWriter out, RoutineDefinition procedure, boolean instance) throws SQLException { // [#281] - Java can't handle more than 255 method parameters if (procedure.getInParameters().size() > 254) { log.warn("Too many parameters", "Procedure " + procedure + " has more than 254 in parameters. Skipping generation of convenience method."); @@ -1683,7 +1798,11 @@ public class DefaultGenerator implements Generator { printThrowsDataAccessException(out); out.println("\t */"); - out.print("\tpublic static "); + out.print("\tpublic "); + + if (!instance) { + out.print("static "); + } if (procedure.getOutParameters().size() == 0) { out.print("void "); @@ -1698,14 +1817,26 @@ public class DefaultGenerator implements Generator { out.print(strategy.getJavaClassNameLC(procedure)); out.print("("); - out.print(Configuration.class); - out.print(" configuration"); + + String glue = ""; + if (!instance) { + out.print(Configuration.class); + out.print(" configuration"); + glue = ", "; + } for (ParameterDefinition parameter : procedure.getInParameters()) { - out.print(", "); + // Skip SELF parameter + if (instance && parameter.equals(procedure.getInParameters().get(0))) { + continue; + } + + out.print(glue); printNumberType(out, parameter.getType()); out.print(" "); out.print(strategy.getJavaClassNameLC(parameter)); + + glue = ", "; } out.println(") {"); @@ -1716,17 +1847,47 @@ public class DefaultGenerator implements Generator { out.println("();"); for (ParameterDefinition parameter : procedure.getInParameters()) { - out.println("\t\tp.set" + strategy.getJavaClassName(parameter) + "(" + strategy.getJavaClassNameLC(parameter) + ");"); + out.print("\t\tp.set"); + out.print(strategy.getJavaClassName(parameter)); + out.print("("); + + if (instance && parameter.equals(procedure.getInParameters().get(0))) { + out.print("this"); + } + else { + out.print(strategy.getJavaClassNameLC(parameter)); + } + + out.println(");"); } out.println(); - out.println("\t\tp.execute(configuration);"); + out.print("\t\tp.execute("); - if (procedure.getOutParameters().size() == 1) { - out.println("\t\treturn p.get" + strategy.getJavaClassName(procedure.getOutParameters().get(0)) + "();"); + if (instance) { + out.print("getConfiguration()"); } - else if (procedure.getOutParameters().size() > 1) { - out.println("\t\treturn p;"); + else { + out.print("configuration"); + } + + out.println(");"); + + if (procedure.getOutParameters().size() > 0) { + if (instance) { + out.print("\t\tfrom(p.get"); + out.print(strategy.getJavaClassName(procedure.getOutParameters().get(0))); + out.println("());"); + } + + if (procedure.getOutParameters().size() == 1) { + out.print("\t\treturn p.get"); + out.print(strategy.getJavaClassName(procedure.getOutParameters().get(0))); + out.println("();"); + } + else if (procedure.getOutParameters().size() > 1) { + out.println("\t\treturn p;"); + } } out.println("\t}"); diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java index 00bdd12683..a6f2bc27eb 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java @@ -360,13 +360,21 @@ public class DefaultGeneratorStrategy implements GeneratorStrategy { else if (definition instanceof TableDefinition) { return "tables"; } + + // [#799] UDT's are also packages + else if (definition instanceof UDTDefinition) { + return "udt"; + } else if (definition instanceof PackageDefinition) { return "packages"; } else if (definition instanceof RoutineDefinition) { RoutineDefinition routine = (RoutineDefinition) definition; - if (routine.getPackage() != null) { + if (routine.getPackage() instanceof UDTDefinition) { + return "udt." + getJavaIdentifierUC(routine.getPackage()).toLowerCase(); + } + else if (routine.getPackage() != null) { return "packages." + getJavaIdentifierUC(routine.getPackage()).toLowerCase(); } else { @@ -379,9 +387,6 @@ public class DefaultGeneratorStrategy implements GeneratorStrategy { else if (definition instanceof ArrayDefinition) { return "udt"; } - else if (definition instanceof UDTDefinition) { - return "udt"; - } // Default always to the main package return ""; diff --git a/jOOQ-meta/src/main/java/org/jooq/util/AbstractUDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/AbstractUDTDefinition.java index a64dc9d64f..c5051b9857 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/AbstractUDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/AbstractUDTDefinition.java @@ -48,6 +48,8 @@ extends implements UDTDefinition { + private List routines; + public AbstractUDTDefinition(Database database, String name, String comment) { super(database, name, comment); } @@ -66,4 +68,15 @@ implements public final AttributeDefinition getAttribute(int attributeIndex) { return getElement(attributeIndex); } + + @Override + public final List getRoutines() { + if (routines == null) { + routines = getRoutines0(); + } + + return routines; + } + + protected abstract List getRoutines0(); } diff --git a/jOOQ-meta/src/main/java/org/jooq/util/UDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/UDTDefinition.java index d5d452bbd6..9d3a4e66bc 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/UDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/UDTDefinition.java @@ -37,13 +37,16 @@ package org.jooq.util; import java.util.List; - /** * A definition for a UDT + *

+ * This extends {@link PackageDefinition} because Oracle internally models UDT's + * in similar ways as packages. This is especially true for the way, member + * procedures and functions are called. * * @author Lukas Eder */ -public interface UDTDefinition extends Definition { +public interface UDTDefinition extends PackageDefinition { /** * All attributes in the UDT @@ -60,4 +63,9 @@ public interface UDTDefinition extends Definition { */ AttributeDefinition getAttribute(int attributeIndex); + /** + * All routines in the UDT + */ + @Override + List getRoutines(); } diff --git a/jOOQ-meta/src/main/java/org/jooq/util/db2/DB2UDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/db2/DB2UDTDefinition.java index 2ed524096f..130ffb326a 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/db2/DB2UDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/db2/DB2UDTDefinition.java @@ -39,6 +39,7 @@ import static org.jooq.util.db2.syscat.tables.Attributes.ATTRIBUTES; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.jooq.Record; @@ -48,6 +49,7 @@ import org.jooq.util.DataTypeDefinition; import org.jooq.util.Database; import org.jooq.util.DefaultAttributeDefinition; import org.jooq.util.DefaultDataTypeDefinition; +import org.jooq.util.RoutineDefinition; import org.jooq.util.db2.syscat.tables.Attributes; /** @@ -93,4 +95,8 @@ public class DB2UDTDefinition extends AbstractUDTDefinition { return result; } + @Override + protected List getRoutines0() { + return Collections.emptyList(); + } } diff --git a/jOOQ-meta/src/main/java/org/jooq/util/oracle/OracleUDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/oracle/OracleUDTDefinition.java index 0b68e2fdf3..928eb436eb 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/oracle/OracleUDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/oracle/OracleUDTDefinition.java @@ -35,6 +35,7 @@ */ package org.jooq.util.oracle; +import static org.jooq.util.oracle.sys.Tables.ALL_ARGUMENTS; import static org.jooq.util.oracle.sys.Tables.ALL_TYPE_ATTRS; import java.sql.SQLException; @@ -48,6 +49,7 @@ import org.jooq.util.DataTypeDefinition; import org.jooq.util.Database; import org.jooq.util.DefaultAttributeDefinition; import org.jooq.util.DefaultDataTypeDefinition; +import org.jooq.util.RoutineDefinition; public class OracleUDTDefinition extends AbstractUDTDefinition { @@ -86,4 +88,32 @@ public class OracleUDTDefinition extends AbstractUDTDefinition { return result; } + + @Override + protected List getRoutines0() { + List result = new ArrayList(); + + for (Record record : create() + .selectDistinct( + ALL_ARGUMENTS.OBJECT_NAME, + ALL_ARGUMENTS.OBJECT_ID, + ALL_ARGUMENTS.OVERLOAD) + .from(ALL_ARGUMENTS) + .where(ALL_ARGUMENTS.OWNER.equal(getSchemaName())) + .and(ALL_ARGUMENTS.PACKAGE_NAME.equal(getName())) + .orderBy( + ALL_ARGUMENTS.OBJECT_NAME, + ALL_ARGUMENTS.OVERLOAD) + .fetch()) { + + result.add(new OracleRoutineDefinition(getDatabase(), + this, + record.getValue(ALL_ARGUMENTS.OBJECT_NAME), + "", + record.getValue(ALL_ARGUMENTS.OBJECT_ID), + record.getValue(ALL_ARGUMENTS.OVERLOAD))); + } + + return result; + } } diff --git a/jOOQ-meta/src/main/java/org/jooq/util/postgres/PostgresUDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/postgres/PostgresUDTDefinition.java index 9ad4d30d87..200a4fa7c6 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/postgres/PostgresUDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/postgres/PostgresUDTDefinition.java @@ -39,6 +39,7 @@ import static org.jooq.util.postgres.information_schema.Tables.ATTRIBUTES; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.jooq.Record; @@ -48,6 +49,7 @@ import org.jooq.util.DataTypeDefinition; import org.jooq.util.Database; import org.jooq.util.DefaultAttributeDefinition; import org.jooq.util.DefaultDataTypeDefinition; +import org.jooq.util.RoutineDefinition; public class PostgresUDTDefinition extends AbstractUDTDefinition { @@ -88,4 +90,9 @@ public class PostgresUDTDefinition extends AbstractUDTDefinition { return result; } + + @Override + protected List getRoutines0() { + return Collections.emptyList(); + } } diff --git a/jOOQ-spring/src/main/java/org/jooq/util/spring/FactoryProxy.java b/jOOQ-spring/src/main/java/org/jooq/util/spring/FactoryProxy.java index 5590c5dbce..afa222435f 100644 --- a/jOOQ-spring/src/main/java/org/jooq/util/spring/FactoryProxy.java +++ b/jOOQ-spring/src/main/java/org/jooq/util/spring/FactoryProxy.java @@ -76,6 +76,8 @@ import org.jooq.Table; import org.jooq.TableLike; import org.jooq.TableRecord; import org.jooq.Truncate; +import org.jooq.UDT; +import org.jooq.UDTRecord; import org.jooq.UpdateQuery; import org.jooq.UpdateSetStep; import org.jooq.exception.DataAccessException; @@ -323,6 +325,11 @@ public class FactoryProxy implements FactoryOperations, MethodInterceptor { return getDelegate().truncate(table); } + @Override + public final > R newRecord(UDT type) { + return getDelegate().newRecord(type); + } + @Override public final > R newRecord(Table table) { return getDelegate().newRecord(table); diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java index cf1c0c89e1..040c41bb91 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java @@ -1102,8 +1102,9 @@ public abstract class jOOQAbstractTest< assertEquals(0, schema.getUDTs().size()); } // [#643] The U_INVALID types are only available in Oracle + // [#799] The member procedure UDT's too else if (getDialect() == SQLDialect.ORACLE) { - assertEquals(5, schema.getUDTs().size()); + assertEquals(7, schema.getUDTs().size()); } else { assertEquals(2, schema.getUDTs().size()); diff --git a/jOOQ-test/src/org/jooq/test/jOOQOracleTest.java b/jOOQ-test/src/org/jooq/test/jOOQOracleTest.java index d64805d513..1ce94b97d8 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQOracleTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQOracleTest.java @@ -37,6 +37,7 @@ package org.jooq.test; import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNull; import static org.jooq.impl.Factory.one; import static org.jooq.impl.Factory.substring; import static org.jooq.impl.Factory.trueCondition; @@ -53,6 +54,9 @@ import static org.jooq.test.oracle.generatedclasses.Tables.T_TRIGGERS; import static org.jooq.test.oracle.generatedclasses.Tables.V_AUTHOR; import static org.jooq.test.oracle.generatedclasses.Tables.V_BOOK; import static org.jooq.test.oracle.generatedclasses.Tables.V_LIBRARY; +import static org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE; +import static org.jooq.test.oracle.generatedclasses.udt.UAuthorType.countBooks; +import static org.jooq.test.oracle.generatedclasses.udt.UAuthorType.load; import static org.jooq.util.oracle.OracleFactory.connectByIsCycle; import static org.jooq.util.oracle.OracleFactory.connectByIsLeaf; import static org.jooq.util.oracle.OracleFactory.level; @@ -101,10 +105,12 @@ import org.jooq.test.oracle.generatedclasses.udt.UInvalidType; import org.jooq.test.oracle.generatedclasses.udt.UStreetType; import org.jooq.test.oracle.generatedclasses.udt.records.OInvalidTypeRecord; import org.jooq.test.oracle.generatedclasses.udt.records.TInvalidTypeRecord; +import org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord; import org.jooq.test.oracle.generatedclasses.udt.records.UInvalidTypeRecord; import org.jooq.test.oracle.generatedclasses.udt.records.UNumberArrayRecord; import org.jooq.test.oracle.generatedclasses.udt.records.UNumberLongArrayRecord; import org.jooq.test.oracle.generatedclasses.udt.records.UStringArrayRecord; +import org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks; import org.jooq.util.oracle.OracleDataType; import org.jooq.util.oracle.OracleFactory; @@ -614,36 +620,38 @@ public class jOOQOracleTest extends jOOQAbstractTest< // Oracle-specific tests // ------------------------------------------------------------------------- + private OracleFactory ora() { + return new OracleFactory(create().getConnection(), create().getSchemaMapping()); + } + @Test public void testOracleConnectBySimple() throws Exception { - OracleFactory ora = new OracleFactory(create().getConnection(), create().getSchemaMapping()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), + ora().select(rownum()) + .connectBy(level().lessThan(10)) + .fetch(rownum())); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), + ora().select(rownum()) + .connectByNoCycle(level().lessThan(10)) + .fetch(rownum())); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), - ora.select(rownum()) - .connectBy(level().lessThan(10)) - .fetch(rownum())); + ora().select(rownum()) + .connectBy(level().lessThan(10)) + .and("1 = ?", 1) + .startWith("? = ?", 1, 1) + .fetch(rownum())); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), - ora.select(rownum()) - .connectByNoCycle(level().lessThan(10)) - .fetch(rownum())); - - assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), - ora.select(rownum()) - .connectBy(level().lessThan(10)) - .and("1 = ?", 1) - .startWith("? = ?", 1, 1) - .fetch(rownum())); - assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), - ora.select(rownum()) - .connectByNoCycle(level().lessThan(10)) - .and("1 = ?", 1) - .startWith("? = ?", 1, 1) - .fetch(rownum())); + ora().select(rownum()) + .connectByNoCycle(level().lessThan(10)) + .and("1 = ?", 1) + .startWith("? = ?", 1, 1) + .fetch(rownum())); Result result = - ora.select(rownum(), connectByIsCycle(), connectByIsLeaf()) - .connectByNoCycle(level().lessThan(4)) - .fetch(); + ora().select(rownum(), connectByIsCycle(), connectByIsLeaf()) + .connectByNoCycle(level().lessThan(4)) + .fetch(); assertEquals(Integer.valueOf(1), result.getValue(0, rownum())); assertEquals(Integer.valueOf(2), result.getValue(1, rownum())); @@ -660,17 +668,15 @@ public class jOOQOracleTest extends jOOQAbstractTest< @Test public void testOracleConnectByDirectory() throws Exception { - OracleFactory ora = new OracleFactory(create().getConnection(), create().getSchemaMapping()); - List paths = - ora.select(substring(sysConnectByPath(TDirectory_NAME(), "/"), 2)) - .from(TDirectory()) - .where(trueCondition()) - .and(trueCondition()) - .connectBy(prior(TDirectory_ID()).equal(TDirectory_PARENT_ID())) - .startWith(TDirectory_PARENT_ID().isNull()) - .orderBy(one()) - .fetch(0); + ora().select(substring(sysConnectByPath(TDirectory_NAME(), "/"), 2)) + .from(TDirectory()) + .where(trueCondition()) + .and(trueCondition()) + .connectBy(prior(TDirectory_ID()).equal(TDirectory_PARENT_ID())) + .startWith(TDirectory_PARENT_ID().isNull()) + .orderBy(one()) + .fetch(0); assertEquals(26, paths.size()); assertEquals(Arrays.asList( @@ -701,4 +707,63 @@ public class jOOQOracleTest extends jOOQAbstractTest< "C:/Program Files/Java/jre6/lib/javaws.jar", "C:/Program Files/Java/jre6/lib/rt.jar"), paths); } + + @Test + public void testMemberProcedures() throws Exception { + UAuthorTypeRecord author1; + UAuthorTypeRecord author2; + + // Unattached: + author1 = new UAuthorTypeRecord(); + author1.setId(1); + author2 = load(ora(), author1); + assertEquals(1, (int) author1.getId()); + assertEquals(1, (int) author2.getId()); + assertNull(author1.getFirstName()); + assertEquals("George", author2.getFirstName()); + assertNull(author1.getLastName()); + assertEquals("Orwell", author2.getLastName()); + + // Attached + author1 = ora().newRecord(U_AUTHOR_TYPE); + author1.setId(1); + author2 = author1.load(); + assertEquals(1, (int) author1.getId()); + assertEquals(1, (int) author2.getId()); + assertEquals("George", author1.getFirstName()); + assertEquals("George", author2.getFirstName()); + assertEquals("Orwell", author1.getLastName()); + assertEquals("Orwell", author2.getLastName()); + + // Count books + author1 = ora().newRecord(U_AUTHOR_TYPE); + assertEquals(BigDecimal.ZERO, author1.countBooks()); + assertEquals(BigDecimal.ZERO, ora().select(countBooks(author1)).fetchOne(0)); + + author1 = ora().newRecord(U_AUTHOR_TYPE); + author1.setId(1); + assertEquals(new BigDecimal("2"), author1.countBooks()); + assertEquals(new BigDecimal("2"), ora().select(countBooks(author1)).fetchOne(0)); + + // Get books + author1 = ora().newRecord(U_AUTHOR_TYPE); + GetBooks noBooks = author1.getBooks(); + assertNull(noBooks.getBook1().getId()); + assertNull(noBooks.getBook1().getTitle()); + assertNull(noBooks.getBook2().getId()); + assertNull(noBooks.getBook2().getTitle()); + + author1 = ora().newRecord(U_AUTHOR_TYPE); + author1.setId(1); + GetBooks books = author1.getBooks(); + assertEquals(1, (int) books.getBook1().getId()); + assertEquals("1984", books.getBook1().getTitle()); + assertEquals(2, (int) books.getBook2().getId()); + assertEquals("Animal Farm", books.getBook2().getTitle()); + + // Get books also calls upon load, internally. Check if that's reflected + assertEquals(1, (int) author1.getId()); + assertEquals("George", author1.getFirstName()); + assertEquals("Orwell", author1.getLastName()); + } } diff --git a/jOOQ-test/src/org/jooq/test/oracle/create.sql b/jOOQ-test/src/org/jooq/test/oracle/create.sql index c0f829b9fe..024ea227f8 100644 --- a/jOOQ-test/src/org/jooq/test/oracle/create.sql +++ b/jOOQ-test/src/org/jooq/test/oracle/create.sql @@ -67,6 +67,96 @@ DROP TYPE o_invalid_type/ DROP TYPE t_invalid_type/ DROP TYPE u_invalid_type/ +DROP TYPE t_book_type/ +DROP TYPE u_author_type/ +DROP TYPE u_book_type/ + +CREATE TYPE u_book_type AS OBJECT ( + id number(7), + title varchar2(400) +) +/ + +CREATE TYPE t_book_type AS TABLE OF u_book_type/ + +CREATE OR REPLACE TYPE u_author_type AS OBJECT ( + id number(7), + first_name varchar2(50), + last_name varchar2(50), + + member procedure load, + member procedure get_books (book1 OUT u_book_type, book2 OUT u_book_type), + + member function count_books return number +) +/ + +CREATE OR REPLACE TYPE BODY u_author_type AS + member procedure load is + x number(7); + begin + x := id; + + if x is not null then + select a.first_name, a.last_name + into first_name, last_name + from t_author a + where a.id = x; + end if; + end load; + + member procedure get_books (book1 OUT u_book_type, book2 OUT u_book_type) is + x number(7); + b1 u_book_type := u_book_type(null, null); + b2 u_book_type := u_book_type(null, null); + begin + x := id; + + -- execute a load to check whether the author is also reloaded + self.load; + + if x is not null then + select b.id, b.title + into b1.id, b1.title + from ( + select b.id, b.title, rownum r + from t_book b + where b.author_id = x + order by b.id + ) b + where b.r = 1; + + select b.id, b.title + into b2.id, b2.title + from ( + select b.id, b.title, rownum r + from t_book b + where b.author_id = x + order by b.id + ) b + where b.r = 2; + end if; + + book1 := b1; + book2 := b2; + end get_books; + + member function count_books return number is + x number(7); + r number(7); + begin + x := id; + + select count(*) + into r + from t_book + where author_id = x; + + return r; + end count_books; +end; +/ + CREATE TYPE u_invalid_type AS invalid/ CREATE TYPE t_invalid_type AS TABLE OF u_invalid_type/ CREATE TYPE o_invalid_type AS OBJECT ( diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/Test.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/Test.java index 42af2b374a..986c494d19 100644 --- a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/Test.java +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/Test.java @@ -10,7 +10,7 @@ package org.jooq.test.oracle.generatedclasses; comments = "This class is generated by jOOQ") public class Test extends org.jooq.impl.SchemaImpl { - private static final long serialVersionUID = 915695249; + private static final long serialVersionUID = 1869611933; /** * The singleton instance of TEST @@ -31,6 +31,8 @@ public class Test extends org.jooq.impl.SchemaImpl { addMapping("TEST.O_INVALID_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.OInvalidTypeRecord.class); addMapping("TEST.T_INVALID_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.TInvalidTypeRecord.class); addMapping("TEST.U_ADDRESS_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.UAddressTypeRecord.class); + addMapping("TEST.U_AUTHOR_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord.class); + addMapping("TEST.U_BOOK_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.UBookTypeRecord.class); addMapping("TEST.U_INVALID_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.UInvalidTypeRecord.class); addMapping("TEST.U_STREET_TYPE", org.jooq.test.oracle.generatedclasses.udt.records.UStreetTypeRecord.class); } @@ -70,6 +72,8 @@ public class Test extends org.jooq.impl.SchemaImpl { org.jooq.test.oracle.generatedclasses.udt.OInvalidType.O_INVALID_TYPE, org.jooq.test.oracle.generatedclasses.udt.TInvalidType.T_INVALID_TYPE, org.jooq.test.oracle.generatedclasses.udt.UAddressType.U_ADDRESS_TYPE, + org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE, + org.jooq.test.oracle.generatedclasses.udt.UBookType.U_BOOK_TYPE, org.jooq.test.oracle.generatedclasses.udt.UInvalidType.U_INVALID_TYPE, org.jooq.test.oracle.generatedclasses.udt.UStreetType.U_STREET_TYPE); } diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/tables/records/XUnusedRecord.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/tables/records/XUnusedRecord.java index bdb23aee15..0d130e61de 100644 --- a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/tables/records/XUnusedRecord.java +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/tables/records/XUnusedRecord.java @@ -12,7 +12,7 @@ package org.jooq.test.oracle.generatedclasses.tables.records; comments = "This class is generated by jOOQ") public class XUnusedRecord extends org.jooq.impl.UpdatableRecordImpl { - private static final long serialVersionUID = 263044219; + private static final long serialVersionUID = 1210920393; /** * An uncommented item @@ -144,8 +144,6 @@ public class XUnusedRecord extends org.jooq.impl.UpdatableRecordImpl implements org.jooq.Package { + + private static final long serialVersionUID = -1306463347; + + /** + * The singleton instance of U_AUTHOR_TYPE + */ + public static final org.jooq.test.oracle.generatedclasses.udt.UAuthorType U_AUTHOR_TYPE = new org.jooq.test.oracle.generatedclasses.udt.UAuthorType(); + + /** + * The class holding records for this type + */ + private static final java.lang.Class __RECORD_TYPE = org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord.class; + + /** + * The class holding records for this type + */ + @Override + public java.lang.Class getRecordType() { + return __RECORD_TYPE; + } + + /** + * An uncommented item + */ + public static final org.jooq.UDTField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER, U_AUTHOR_TYPE); + + /** + * An uncommented item + */ + public static final org.jooq.UDTField FIRST_NAME = createField("FIRST_NAME", org.jooq.impl.SQLDataType.VARCHAR, U_AUTHOR_TYPE); + + /** + * An uncommented item + */ + public static final org.jooq.UDTField LAST_NAME = createField("LAST_NAME", org.jooq.impl.SQLDataType.VARCHAR, U_AUTHOR_TYPE); + + /** + * Invoke COUNT_BOOKS + * + * @param self + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public static java.math.BigDecimal countBooks(org.jooq.Configuration configuration, org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord self) { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks f = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks(); + f.setSelf(self); + + f.execute(configuration); + return f.getReturnValue(); + } + + /** + * Get COUNT_BOOKS as a field + * + * @param self + */ + public static org.jooq.Field countBooks(org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord self) { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks f = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks(); + f.setSelf(self); + + return f.asField(); + } + + /** + * Get COUNT_BOOKS as a field + * + * @param self + */ + public static org.jooq.Field countBooks(org.jooq.Field self) { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks f = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks(); + f.setSelf(self); + + return f.asField(); + } + + /** + * Invoke GET_BOOKS + * + * @param self IN OUT parameter + * @param book1 OUT parameter + * @param book2 OUT parameter + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public static org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks getBooks(org.jooq.Configuration configuration, org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord self) { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks p = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks(); + p.setSelf(self); + + p.execute(configuration); + return p; + } + + /** + * Invoke LOAD + * + * @param self IN OUT parameter + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public static org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord load(org.jooq.Configuration configuration, org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord self) { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.Load p = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.Load(); + p.setSelf(self); + + p.execute(configuration); + return p.getSelf(); + } + + /** + * No further instances allowed + */ + private UAuthorType() { + super("U_AUTHOR_TYPE", org.jooq.test.oracle.generatedclasses.Test.TEST); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/UBookType.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/UBookType.java new file mode 100644 index 0000000000..21cd920987 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/UBookType.java @@ -0,0 +1,49 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class UBookType extends org.jooq.impl.UDTImpl { + + private static final long serialVersionUID = 1693876579; + + /** + * The singleton instance of U_BOOK_TYPE + */ + public static final org.jooq.test.oracle.generatedclasses.udt.UBookType U_BOOK_TYPE = new org.jooq.test.oracle.generatedclasses.udt.UBookType(); + + /** + * The class holding records for this type + */ + private static final java.lang.Class __RECORD_TYPE = org.jooq.test.oracle.generatedclasses.udt.records.UBookTypeRecord.class; + + /** + * The class holding records for this type + */ + @Override + public java.lang.Class getRecordType() { + return __RECORD_TYPE; + } + + /** + * An uncommented item + */ + public static final org.jooq.UDTField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER, U_BOOK_TYPE); + + /** + * An uncommented item + */ + public static final org.jooq.UDTField TITLE = createField("TITLE", org.jooq.impl.SQLDataType.VARCHAR, U_BOOK_TYPE); + + /** + * No further instances allowed + */ + private UBookType() { + super("U_BOOK_TYPE", org.jooq.test.oracle.generatedclasses.Test.TEST); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UAuthorTypeRecord.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UAuthorTypeRecord.java new file mode 100644 index 0000000000..dbff401715 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UAuthorTypeRecord.java @@ -0,0 +1,107 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt.records; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class UAuthorTypeRecord extends org.jooq.impl.UDTRecordImpl { + + private static final long serialVersionUID = 1355125548; + + + /** + * An uncommented item + */ + public void setId(java.lang.Integer value) { + setValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.ID, value); + } + + /** + * An uncommented item + */ + public java.lang.Integer getId() { + return getValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.ID); + } + + /** + * An uncommented item + */ + public void setFirstName(java.lang.String value) { + setValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.FIRST_NAME, value); + } + + /** + * An uncommented item + */ + public java.lang.String getFirstName() { + return getValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.FIRST_NAME); + } + + /** + * An uncommented item + */ + public void setLastName(java.lang.String value) { + setValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.LAST_NAME, value); + } + + /** + * An uncommented item + */ + public java.lang.String getLastName() { + return getValue(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.LAST_NAME); + } + + /** + * Invoke COUNT_BOOKS + * + * @param self + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public java.math.BigDecimal countBooks() { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks f = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.CountBooks(); + f.setSelf(this); + + f.execute(getConfiguration()); + return f.getReturnValue(); + } + + /** + * Invoke GET_BOOKS + * + * @param self IN OUT parameter + * @param book1 OUT parameter + * @param book2 OUT parameter + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks getBooks() { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks p = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.GetBooks(); + p.setSelf(this); + + p.execute(getConfiguration()); + from(p.getSelf()); + return p; + } + + /** + * Invoke LOAD + * + * @param self IN OUT parameter + * @throws org.jooq.exception.DataAccessException if something went wrong executing the query + */ + public org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord load() { + org.jooq.test.oracle.generatedclasses.udt.u_author_type.Load p = new org.jooq.test.oracle.generatedclasses.udt.u_author_type.Load(); + p.setSelf(this); + + p.execute(getConfiguration()); + from(p.getSelf()); + return p.getSelf(); + } + + public UAuthorTypeRecord() { + super(org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UBookTypeRecord.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UBookTypeRecord.java new file mode 100644 index 0000000000..54ac550399 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/records/UBookTypeRecord.java @@ -0,0 +1,47 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt.records; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class UBookTypeRecord extends org.jooq.impl.UDTRecordImpl { + + private static final long serialVersionUID = -1694057466; + + + /** + * An uncommented item + */ + public void setId(java.lang.Integer value) { + setValue(org.jooq.test.oracle.generatedclasses.udt.UBookType.ID, value); + } + + /** + * An uncommented item + */ + public java.lang.Integer getId() { + return getValue(org.jooq.test.oracle.generatedclasses.udt.UBookType.ID); + } + + /** + * An uncommented item + */ + public void setTitle(java.lang.String value) { + setValue(org.jooq.test.oracle.generatedclasses.udt.UBookType.TITLE, value); + } + + /** + * An uncommented item + */ + public java.lang.String getTitle() { + return getValue(org.jooq.test.oracle.generatedclasses.udt.UBookType.TITLE); + } + + public UBookTypeRecord() { + super(org.jooq.test.oracle.generatedclasses.udt.UBookType.U_BOOK_TYPE); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/CountBooks.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/CountBooks.java new file mode 100644 index 0000000000..2d94640c98 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/CountBooks.java @@ -0,0 +1,51 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt.u_author_type; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class CountBooks extends org.jooq.impl.AbstractRoutine { + + private static final long serialVersionUID = -737595056; + + + /** + * An uncommented item + */ + public static final org.jooq.Parameter RETURN_VALUE = createParameter("RETURN_VALUE", org.jooq.impl.SQLDataType.NUMERIC); + + /** + * An uncommented item + */ + public static final org.jooq.Parameter SELF = createParameter("SELF", org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE.getDataType()); + + /** + * Create a new routine call instance + */ + public CountBooks() { + super(org.jooq.SQLDialect.ORACLE, "COUNT_BOOKS", org.jooq.test.oracle.generatedclasses.Test.TEST, org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE, org.jooq.impl.SQLDataType.NUMERIC); + + setReturnParameter(RETURN_VALUE); + addInParameter(SELF); + } + + /** + * Set the SELF parameter to the routine + */ + public void setSelf(org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord value) { + setValue(SELF, value); + } + + /** + * Set the SELF parameter to the function + *

+ * Use this method only, if the function is called as a {@link org.jooq.Field} in a {@link org.jooq.Select} statement! + */ + public void setSelf(org.jooq.Field field) { + setField(SELF, field); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/GetBooks.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/GetBooks.java new file mode 100644 index 0000000000..8d13a71fe7 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/GetBooks.java @@ -0,0 +1,60 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt.u_author_type; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class GetBooks extends org.jooq.impl.AbstractRoutine { + + private static final long serialVersionUID = 1050061777; + + + /** + * An uncommented item + */ + public static final org.jooq.Parameter SELF = createParameter("SELF", org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE.getDataType()); + + /** + * An uncommented item + */ + public static final org.jooq.Parameter BOOK1 = createParameter("BOOK1", org.jooq.test.oracle.generatedclasses.udt.UBookType.U_BOOK_TYPE.getDataType()); + + /** + * An uncommented item + */ + public static final org.jooq.Parameter BOOK2 = createParameter("BOOK2", org.jooq.test.oracle.generatedclasses.udt.UBookType.U_BOOK_TYPE.getDataType()); + + /** + * Create a new routine call instance + */ + public GetBooks() { + super(org.jooq.SQLDialect.ORACLE, "GET_BOOKS", org.jooq.test.oracle.generatedclasses.Test.TEST, org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE); + + addInOutParameter(SELF); + addOutParameter(BOOK1); + addOutParameter(BOOK2); + } + + /** + * Set the SELF parameter to the routine + */ + public void setSelf(org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord value) { + setValue(SELF, value); + } + + public org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord getSelf() { + return getValue(SELF); + } + + public org.jooq.test.oracle.generatedclasses.udt.records.UBookTypeRecord getBook1() { + return getValue(BOOK1); + } + + public org.jooq.test.oracle.generatedclasses.udt.records.UBookTypeRecord getBook2() { + return getValue(BOOK2); + } +} diff --git a/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/Load.java b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/Load.java new file mode 100644 index 0000000000..eebbbf0fe4 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/oracle/generatedclasses/udt/u_author_type/Load.java @@ -0,0 +1,40 @@ +/** + * This class is generated by jOOQ + */ +package org.jooq.test.oracle.generatedclasses.udt.u_author_type; + +/** + * This class is generated by jOOQ. + */ +@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.0"}, + comments = "This class is generated by jOOQ") +public class Load extends org.jooq.impl.AbstractRoutine { + + private static final long serialVersionUID = -1417820903; + + + /** + * An uncommented item + */ + public static final org.jooq.Parameter SELF = createParameter("SELF", org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE.getDataType()); + + /** + * Create a new routine call instance + */ + public Load() { + super(org.jooq.SQLDialect.ORACLE, "LOAD", org.jooq.test.oracle.generatedclasses.Test.TEST, org.jooq.test.oracle.generatedclasses.udt.UAuthorType.U_AUTHOR_TYPE); + + addInOutParameter(SELF); + } + + /** + * Set the SELF parameter to the routine + */ + public void setSelf(org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord value) { + setValue(SELF, value); + } + + public org.jooq.test.oracle.generatedclasses.udt.records.UAuthorTypeRecord getSelf() { + return getValue(SELF); + } +} diff --git a/jOOQ/src/main/java/org/jooq/FactoryOperations.java b/jOOQ/src/main/java/org/jooq/FactoryOperations.java index 330bfae323..5e3b492f43 100644 --- a/jOOQ/src/main/java/org/jooq/FactoryOperations.java +++ b/jOOQ/src/main/java/org/jooq/FactoryOperations.java @@ -655,6 +655,15 @@ public interface FactoryOperations extends Configuration { // Global Record factory // ------------------------------------------------------------------------- + /** + * Create a new attached {@link UDTRecord}. + * + * @param The generic record type + * @param type The UDT describing records of type <R> + * @return The new record + */ + > R newRecord(UDT type); + /** * Create a new {@link Record} that can be inserted into the corresponding * table. diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index 34ca5caa93..7a813e81b3 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -599,6 +599,20 @@ abstract class AbstractRecord extends AbstractStore implements Record { } } + /** + * This method was implemented with [#799]. It may be useful to make it + * public for broader use...? + */ + protected final void from(Record source) { + for (Field field : getFields()) { + Field sourceField = source.getField(field); + + if (sourceField != null) { + Util.setValue(this, field, source, sourceField); + } + } + } + private final void into(Object result, java.lang.reflect.Field member, Field field) throws IllegalAccessException { Class mType = member.getType(); diff --git a/jOOQ/src/main/java/org/jooq/impl/Factory.java b/jOOQ/src/main/java/org/jooq/impl/Factory.java index 8fe5d80952..028bba964c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Factory.java +++ b/jOOQ/src/main/java/org/jooq/impl/Factory.java @@ -97,6 +97,7 @@ import org.jooq.Table; import org.jooq.TableLike; import org.jooq.TableRecord; import org.jooq.Truncate; +import org.jooq.UDT; import org.jooq.UDTRecord; import org.jooq.UpdateQuery; import org.jooq.UpdateSetStep; @@ -1145,6 +1146,14 @@ public class Factory implements FactoryOperations { // Global Record factory // ------------------------------------------------------------------------- + /** + * {@inheritDoc} + */ + @Override + public final > R newRecord(UDT type) { + return Util.newRecord(type, this); + } + /** * {@inheritDoc} */ diff --git a/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java b/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java index 1adc25add6..955b1c86f7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java +++ b/jOOQ/src/main/java/org/jooq/impl/UDTConstant.java @@ -109,9 +109,12 @@ class UDTConstant> extends AbstractField { return; } - } - throw new SQLDialectNotSupportedException("UDTs not supported in dialect " + context.getDialect()); + // Assume default behaviour if dialect is not available + default: + toSQLInline(context); + return; + } } private void toSQLInline(RenderContext context) { @@ -133,8 +136,11 @@ class UDTConstant> extends AbstractField { case POSTGRES: return "ROW"; - case ORACLE: // No break - case DB2: { + case ORACLE: + case DB2: + + // Assume default behaviour if dialect is not available + default: { UDT udt = record.getUDT(); if (getMappedSchema(context, udt.getSchema()) != null) { @@ -145,8 +151,6 @@ class UDTConstant> extends AbstractField { } } } - - throw new SQLDialectNotSupportedException("UDTs not supported in dialect " + context.getDialect()); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/UDTImpl.java b/jOOQ/src/main/java/org/jooq/impl/UDTImpl.java index f6f0ceb2ce..b9cf21ca5b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UDTImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/UDTImpl.java @@ -44,6 +44,7 @@ import org.jooq.Attachable; import org.jooq.BindContext; import org.jooq.DataType; import org.jooq.Field; +import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.RenderContext; import org.jooq.Schema; @@ -119,12 +120,12 @@ public class UDTImpl> extends AbstractType implements @Override public final void toSQL(RenderContext context) { - throw new UnsupportedOperationException("UDTImpl cannot be used as a true QueryPart"); + context.literal(getName()); } @Override public final void bind(BindContext context) { - throw new UnsupportedOperationException("UDTImpl cannot be used as a true QueryPart"); + context.bind((QueryPart) fields); } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/Util.java b/jOOQ/src/main/java/org/jooq/impl/Util.java index 073a91786a..4fc7dcbc7f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Util.java +++ b/jOOQ/src/main/java/org/jooq/impl/Util.java @@ -57,7 +57,7 @@ import org.jooq.FieldProvider; import org.jooq.NamedQueryPart; import org.jooq.Record; import org.jooq.RenderContext; -import org.jooq.Table; +import org.jooq.Type; import org.jooq.exception.DataAccessException; import org.jooq.tools.StringUtils; @@ -106,15 +106,15 @@ final class Util { /** * Create a new record */ - static R newRecord(Table table) { - return newRecord(table, null); + static R newRecord(Type type) { + return newRecord(type, null); } /** * Create a new record */ - static R newRecord(Table table, Configuration configuration) { - return newRecord(table.getRecordType(), table, configuration); + static R newRecord(Type type, Configuration configuration) { + return newRecord(type.getRecordType(), type, configuration); } /**