[#2530] First working draft
This commit is contained in:
parent
6e8b2d97db
commit
04d03bfda0
@ -72,6 +72,7 @@ abstract class AbstractGenerator implements Generator {
|
||||
boolean generateSequences = true;
|
||||
boolean generateUDTs = true;
|
||||
boolean generateTables = true;
|
||||
boolean generateEmbeddables = true;
|
||||
boolean generateRecords = true;
|
||||
boolean generateRecordsImplementingRecordN = true;
|
||||
boolean generatePojos = false;
|
||||
@ -356,6 +357,16 @@ abstract class AbstractGenerator implements Generator {
|
||||
this.generateTables = generateTables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateEmbeddables() {
|
||||
return generateEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateEmbeddables(boolean generateEmbeddables) {
|
||||
this.generateEmbeddables = generateEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateRecords() {
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@ import org.jooq.meta.ArrayDefinition;
|
||||
import org.jooq.meta.CatalogDefinition;
|
||||
import org.jooq.meta.Definition;
|
||||
import org.jooq.meta.DomainDefinition;
|
||||
import org.jooq.meta.EmbeddableDefinition;
|
||||
import org.jooq.meta.EnumDefinition;
|
||||
import org.jooq.meta.ForeignKeyDefinition;
|
||||
import org.jooq.meta.IndexDefinition;
|
||||
@ -294,15 +295,12 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
.replace('.', '_')
|
||||
));
|
||||
|
||||
if (mode == Mode.RECORD) {
|
||||
if (mode == Mode.RECORD)
|
||||
result.append("Record");
|
||||
}
|
||||
else if (mode == Mode.DAO) {
|
||||
else if (mode == Mode.DAO)
|
||||
result.append("Dao");
|
||||
}
|
||||
else if (mode == Mode.INTERFACE) {
|
||||
else if (mode == Mode.INTERFACE)
|
||||
result.insert(0, "I");
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
@ -312,6 +310,11 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
return "tables";
|
||||
}
|
||||
|
||||
// [#2530] Embeddable types
|
||||
else if (definition instanceof EmbeddableDefinition) {
|
||||
return "embeddables";
|
||||
}
|
||||
|
||||
// [#799] UDT's are also packages
|
||||
else if (definition instanceof UDTDefinition) {
|
||||
UDTDefinition udt = (UDTDefinition) definition;
|
||||
|
||||
@ -490,6 +490,7 @@ public class GenerationTool {
|
||||
database.setIncludeRoutines(!FALSE.equals(d.isIncludeRoutines()));
|
||||
database.setIncludeSequences(!FALSE.equals(d.isIncludeSequences()));
|
||||
database.setIncludeTables(!FALSE.equals(d.isIncludeTables()));
|
||||
database.setIncludeEmbeddables(!FALSE.equals(d.isIncludeEmbeddables()));
|
||||
database.setIncludeTriggerRoutines(TRUE.equals(d.isIncludeTriggerRoutines()));
|
||||
database.setIncludeUDTs(!FALSE.equals(d.isIncludeUDTs()));
|
||||
database.setIncludeUniqueKeys(!FALSE.equals(d.isIncludeUniqueKeys()));
|
||||
@ -502,6 +503,7 @@ public class GenerationTool {
|
||||
database.setConfiguredCustomTypes(d.getCustomTypes());
|
||||
database.setConfiguredEnumTypes(d.getEnumTypes());
|
||||
database.setConfiguredForcedTypes(d.getForcedTypes());
|
||||
database.setConfiguredEmbeddables(d.getEmbeddables());
|
||||
database.setLogSlowQueriesAfterSeconds(defaultIfNull(g.getDatabase().getLogSlowQueriesAfterSeconds(), 5));
|
||||
|
||||
if (d.getRegexFlags() != null)
|
||||
@ -616,6 +618,8 @@ public class GenerationTool {
|
||||
generator.setGenerateUDTs(g.getGenerate().isUdts());
|
||||
if (g.getGenerate().isTables() != null)
|
||||
generator.setGenerateTables(g.getGenerate().isTables());
|
||||
if (g.getGenerate().isEmbeddables() != null)
|
||||
generator.setGenerateEmbeddables(g.getGenerate().isEmbeddables());
|
||||
if (g.getGenerate().isRecords() != null)
|
||||
generator.setGenerateRecords(g.getGenerate().isRecords());
|
||||
if (g.getGenerate().isRecordsImplementingRecordN() != null)
|
||||
|
||||
@ -202,6 +202,16 @@ public interface Generator {
|
||||
*/
|
||||
void setGenerateTables(boolean generateTables);
|
||||
|
||||
/**
|
||||
* Whether embeddable types should be generated
|
||||
*/
|
||||
boolean generateEmbeddables();
|
||||
|
||||
/**
|
||||
* Whether embeddable types should be generated
|
||||
*/
|
||||
void setGenerateEmbeddables(boolean generateEmbeddables);
|
||||
|
||||
/**
|
||||
* Whether TableRecords should be generated in addition to tables
|
||||
*/
|
||||
|
||||
@ -111,6 +111,7 @@ import org.jooq.impl.CatalogImpl;
|
||||
import org.jooq.impl.DAOImpl;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.DefaultDataType;
|
||||
import org.jooq.impl.EmbeddableRecordImpl;
|
||||
import org.jooq.impl.Internal;
|
||||
import org.jooq.impl.PackageImpl;
|
||||
import org.jooq.impl.SQLDataType;
|
||||
@ -131,6 +132,8 @@ import org.jooq.meta.Database;
|
||||
import org.jooq.meta.DefaultDataTypeDefinition;
|
||||
import org.jooq.meta.Definition;
|
||||
import org.jooq.meta.DomainDefinition;
|
||||
import org.jooq.meta.EmbeddableColumnDefinition;
|
||||
import org.jooq.meta.EmbeddableDefinition;
|
||||
import org.jooq.meta.EnumDefinition;
|
||||
import org.jooq.meta.ForeignKeyDefinition;
|
||||
import org.jooq.meta.IdentityDefinition;
|
||||
@ -507,6 +510,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
generateTables(schema);
|
||||
}
|
||||
|
||||
if (generateEmbeddables() && database.getEmbeddables(schema).size() > 0) {
|
||||
generateEmbeddables(schema);
|
||||
}
|
||||
|
||||
if (generatePojos() && database.getTables(schema).size() > 0) {
|
||||
generatePojos(schema);
|
||||
}
|
||||
@ -1011,7 +1018,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println();
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("private object Identities%s {", block);
|
||||
out.tab(1).println("private object Identities%s {", block);
|
||||
else
|
||||
out.tab(1).println("private static class Identities%s {", block);
|
||||
}
|
||||
@ -1063,7 +1070,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println();
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("private object UniqueKeys%s {", block);
|
||||
out.tab(1).println("private object UniqueKeys%s {", block);
|
||||
else
|
||||
out.tab(1).println("private static class UniqueKeys%s {", block);
|
||||
}
|
||||
@ -1114,13 +1121,13 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println();
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("private object ForeignKeys%s {", block);
|
||||
out.tab(1).println("private object ForeignKeys%s {", block);
|
||||
else
|
||||
out.tab(1).println("private static class ForeignKeys%s {", block);
|
||||
}
|
||||
|
||||
if (scala)
|
||||
out.tab(2).println("val %s : %s[%s, %s] = %s.createForeignKey(%s, %s, \"%s\", [[%s]])",
|
||||
out.tab(2).println("val %s : %s[%s, %s] = %s.createForeignKey(%s, %s, \"%s\", [[%s]])",
|
||||
getStrategy().getJavaIdentifier(foreignKey),
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
@ -1180,29 +1187,35 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
generateRecord0(udt, out);
|
||||
}
|
||||
|
||||
private final void generateRecord0(Definition tableOrUdt, JavaWriter out) {
|
||||
final UniqueKeyDefinition key = (tableOrUdt instanceof TableDefinition)
|
||||
? ((TableDefinition) tableOrUdt).getPrimaryKey()
|
||||
private final void generateRecord0(Definition tableUdtOrEmbeddable, JavaWriter out) {
|
||||
final UniqueKeyDefinition key = (tableUdtOrEmbeddable instanceof TableDefinition)
|
||||
? ((TableDefinition) tableUdtOrEmbeddable).getPrimaryKey()
|
||||
: null;
|
||||
final String className = getStrategy().getJavaClassName(tableOrUdt, Mode.RECORD);
|
||||
final String tableIdentifier = out.ref(getStrategy().getFullJavaIdentifier(tableOrUdt), 2);
|
||||
final List<String> interfaces = out.ref(getStrategy().getJavaClassImplements(tableOrUdt, Mode.RECORD));
|
||||
final List<? extends TypedElementDefinition<?>> columns = getTypedElements(tableOrUdt);
|
||||
final String className = getStrategy().getJavaClassName(tableUdtOrEmbeddable, Mode.RECORD);
|
||||
final String tableIdentifier = !(tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
? out.ref(getStrategy().getFullJavaIdentifier(tableUdtOrEmbeddable), 2)
|
||||
: null;
|
||||
final List<String> interfaces = out.ref(getStrategy().getJavaClassImplements(tableUdtOrEmbeddable, Mode.RECORD));
|
||||
final List<? extends TypedElementDefinition<?>> columns = getTypedElements(tableUdtOrEmbeddable);
|
||||
|
||||
printPackage(out, tableOrUdt, Mode.RECORD);
|
||||
printPackage(out, tableUdtOrEmbeddable, Mode.RECORD);
|
||||
|
||||
if (tableOrUdt instanceof TableDefinition)
|
||||
generateRecordClassJavadoc((TableDefinition) tableOrUdt, out);
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition)
|
||||
generateRecordClassJavadoc((TableDefinition) tableUdtOrEmbeddable, out);
|
||||
else if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
generateEmbeddableClassJavadoc((EmbeddableDefinition) tableUdtOrEmbeddable, out);
|
||||
else
|
||||
generateUDTRecordClassJavadoc((UDTDefinition) tableOrUdt, out);
|
||||
generateUDTRecordClassJavadoc((UDTDefinition) tableUdtOrEmbeddable, out);
|
||||
|
||||
printClassAnnotations(out, tableOrUdt.getSchema());
|
||||
if (tableOrUdt instanceof TableDefinition)
|
||||
printTableJPAAnnotation(out, (TableDefinition) tableOrUdt);
|
||||
printClassAnnotations(out, tableUdtOrEmbeddable.getSchema());
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition)
|
||||
printTableJPAAnnotation(out, (TableDefinition) tableUdtOrEmbeddable);
|
||||
|
||||
Class<?> baseClass;
|
||||
if (tableOrUdt instanceof UDTDefinition)
|
||||
if (tableUdtOrEmbeddable instanceof UDTDefinition)
|
||||
baseClass = UDTRecordImpl.class;
|
||||
else if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
baseClass = EmbeddableRecordImpl.class;
|
||||
else if (generateRelations() && key != null)
|
||||
baseClass = UpdatableRecordImpl.class;
|
||||
else
|
||||
@ -1225,12 +1238,14 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
interfaces.add(rowTypeRecord);
|
||||
}
|
||||
|
||||
if (generateInterfaces()) {
|
||||
interfaces.add(out.ref(getStrategy().getFullJavaClassName(tableOrUdt, Mode.INTERFACE)));
|
||||
}
|
||||
if (generateInterfaces())
|
||||
interfaces.add(out.ref(getStrategy().getFullJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE)));
|
||||
|
||||
if (scala)
|
||||
out.println("class %s extends %s[%s](%s)[[before= with ][separator= with ][%s]] {", className, baseClass, className, tableIdentifier, interfaces);
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("class %s extends %s[%s]()[[before= with ][separator= with ][%s]] {", className, baseClass, className, interfaces);
|
||||
else
|
||||
out.println("class %s extends %s[%s](%s)[[before= with ][separator= with ][%s]] {", className, baseClass, className, tableIdentifier, interfaces);
|
||||
else
|
||||
out.println("public class %s extends %s<%s>[[before= implements ][%s]] {", className, baseClass, className, interfaces);
|
||||
|
||||
@ -1239,16 +1254,30 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
for (int i = 0; i < degree; i++) {
|
||||
TypedElementDefinition<?> column = columns.get(i);
|
||||
|
||||
if (tableOrUdt instanceof TableDefinition) {
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition) {
|
||||
generateRecordSetter(column, i, out);
|
||||
generateRecordGetter(column, i, out);
|
||||
}
|
||||
else if (tableUdtOrEmbeddable instanceof EmbeddableDefinition) {
|
||||
generateEmbeddableSetter(column, i, out);
|
||||
generateEmbeddableGetter(column, i, out);
|
||||
}
|
||||
else {
|
||||
generateUDTRecordSetter(column, i, out);
|
||||
generateUDTRecordGetter(column, i, out);
|
||||
}
|
||||
}
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition) {
|
||||
List<EmbeddableDefinition> embeddables = ((TableDefinition) tableUdtOrEmbeddable).getEmbeddables();
|
||||
|
||||
for (int i = 0; i < embeddables.size(); i++) {
|
||||
EmbeddableDefinition embeddable = embeddables.get(i);
|
||||
|
||||
// [#2530] TODO: Implement setters and getters for embeddables here
|
||||
}
|
||||
}
|
||||
|
||||
if (generateRelations() && key != null) {
|
||||
int keyDegree = key.getKeyColumns().size();
|
||||
|
||||
@ -1270,10 +1299,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (tableOrUdt instanceof UDTDefinition) {
|
||||
if (tableUdtOrEmbeddable instanceof UDTDefinition) {
|
||||
|
||||
// [#799] Oracle UDT's can have member procedures
|
||||
for (RoutineDefinition routine : ((UDTDefinition) tableOrUdt).getRoutines()) {
|
||||
for (RoutineDefinition routine : ((UDTDefinition) tableUdtOrEmbeddable).getRoutines()) {
|
||||
|
||||
// Instance methods ship with a SELF parameter at the first position
|
||||
// [#1584] Static methods don't have that
|
||||
@ -1334,6 +1363,9 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
for (int i = 1; i <= degree; i++) {
|
||||
TypedElementDefinition<?> column = columns.get(i - 1);
|
||||
|
||||
if (column instanceof EmbeddableColumnDefinition)
|
||||
column = ((EmbeddableColumnDefinition) column).getColumn();
|
||||
|
||||
final String colTypeFull = getJavaType(column.getType(resolver()));
|
||||
final String colType = out.ref(colTypeFull);
|
||||
final String colIdentifier = out.ref(getStrategy().getFullJavaIdentifier(column), colRefSegments(column));
|
||||
@ -1349,7 +1381,12 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).overrideInherit();
|
||||
|
||||
out.tab(1).println("public %s<%s> field%s() {", Field.class, colType, i);
|
||||
out.tab(2).println("return %s;", colIdentifier);
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.tab(2).println("return (%s<%s>) FIELDS[%s];", Field.class, colType, i - 1);
|
||||
else
|
||||
out.tab(2).println("return %s;", colIdentifier);
|
||||
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
}
|
||||
@ -1471,17 +1508,35 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (generateInterfaces()) {
|
||||
printFromAndInto(out, tableOrUdt);
|
||||
}
|
||||
if (generateInterfaces())
|
||||
printFromAndInto(out, tableUdtOrEmbeddable);
|
||||
|
||||
if (scala) {
|
||||
}
|
||||
else {
|
||||
out.tab(1).header("Constructors");
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition) {
|
||||
out.println();
|
||||
out.tab(1).println("private static final %s<?>[] FIELDS = {", Field.class);
|
||||
|
||||
for (EmbeddableColumnDefinition column : ((EmbeddableDefinition) tableUdtOrEmbeddable).getColumns()) {
|
||||
final String colIdentifier = out.ref(getStrategy().getFullJavaIdentifier(column.getColumn()), colRefSegments(column));
|
||||
|
||||
out.tab(2).println("%s.field(%s.name(\"%s\"), %s.getDataType()),", DSL.class, DSL.class, column.getOutputName(), colIdentifier);
|
||||
}
|
||||
|
||||
out.tab(1).println("};");
|
||||
out.println();
|
||||
}
|
||||
|
||||
out.tab(1).javadoc("Create a detached %s", className);
|
||||
|
||||
out.tab(1).println("public %s() {", className);
|
||||
out.tab(2).println("super(%s);", tableIdentifier);
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.tab(2).println("super(FIELDS);");
|
||||
else
|
||||
out.tab(2).println("super(%s);", tableIdentifier);
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
|
||||
@ -1496,7 +1551,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
final String type = out.ref(getJavaType(column.getType(resolver())));
|
||||
|
||||
if (scala)
|
||||
arguments.add(columnMember + " : " + type);
|
||||
arguments.add(columnMember + " : " + type);
|
||||
else
|
||||
arguments.add(type + " " + columnMember);
|
||||
}
|
||||
@ -1509,7 +1564,11 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
else {
|
||||
out.tab(1).println("public %s([[%s]]) {", className, arguments);
|
||||
out.tab(2).println("super(%s);", tableIdentifier);
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.tab(2).println("this();", tableIdentifier);
|
||||
else
|
||||
out.tab(2).println("super(%s);", tableIdentifier);
|
||||
}
|
||||
|
||||
out.println();
|
||||
@ -1519,7 +1578,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
final String columnMember = getStrategy().getJavaMemberName(column, Mode.DEFAULT);
|
||||
|
||||
if (scala)
|
||||
out.tab(2).println("set(%s, %s)", i, columnMember);
|
||||
out.tab(2).println("set(%s, %s)", i, columnMember);
|
||||
else
|
||||
out.tab(2).println("set(%s, %s);", i, columnMember);
|
||||
}
|
||||
@ -1527,10 +1586,12 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
|
||||
if (tableOrUdt instanceof TableDefinition)
|
||||
generateRecordClassFooter((TableDefinition) tableOrUdt, out);
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition)
|
||||
generateRecordClassFooter((TableDefinition) tableUdtOrEmbeddable, out);
|
||||
else if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
generateEmbeddableClassFooter((EmbeddableDefinition) tableUdtOrEmbeddable, out);
|
||||
else
|
||||
generateUDTRecordClassFooter((UDTDefinition) tableOrUdt, out);
|
||||
generateUDTRecordClassFooter((UDTDefinition) tableUdtOrEmbeddable, out);
|
||||
|
||||
out.println("}");
|
||||
}
|
||||
@ -1542,6 +1603,13 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
generateRecordSetter0(column, index, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own embeddable setters.
|
||||
*/
|
||||
protected void generateEmbeddableSetter(TypedElementDefinition<?> column, int index, JavaWriter out) {
|
||||
generateRecordSetter0(column, index, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own record setters.
|
||||
*/
|
||||
@ -1651,6 +1719,13 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
generateRecordGetter0(column, index, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own embeddable getters.
|
||||
*/
|
||||
protected void generateEmbeddableGetter(TypedElementDefinition<?> column, int index, JavaWriter out) {
|
||||
generateRecordGetter0(column, index, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own record getters.
|
||||
*/
|
||||
@ -1668,7 +1743,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
if (!printDeprecationIfUnknownType(out, typeFull))
|
||||
out.tab(1).javadoc("Getter for <code>%s</code>.%s", name, columnComment(column, comment));
|
||||
|
||||
if (column.getContainer() instanceof TableDefinition)
|
||||
if (column instanceof ColumnDefinition)
|
||||
printColumnJPAAnnotation(out, (ColumnDefinition) column);
|
||||
printValidationAnnotation(out, column);
|
||||
|
||||
@ -1718,6 +1793,19 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printClassJavadoc(out, "The table <code>" + table.getQualifiedInputName() + "</code>.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide record class footer code.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void generateEmbeddableClassFooter(EmbeddableDefinition embeddable, JavaWriter out) {}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own Javadoc.
|
||||
*/
|
||||
protected void generateEmbeddableClassJavadoc(EmbeddableDefinition embeddable, JavaWriter out) {
|
||||
printClassJavadoc(out, "The embeddable <code>" + embeddable.getQualifiedInputName() + "</code>.");
|
||||
}
|
||||
|
||||
private String refRowType(JavaWriter out, Collection<? extends TypedElementDefinition<?>> columns) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
String separator = "";
|
||||
@ -1784,7 +1872,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printTableJPAAnnotation(out, (TableDefinition) tableOrUDT);
|
||||
|
||||
if (scala)
|
||||
out.println("trait %s[[before= extends ][%s]] {", className, interfaces);
|
||||
out.println("trait %s[[before= extends ][%s]] {", className, interfaces);
|
||||
else
|
||||
out.println("public interface %s[[before= extends ][%s]] {", className, interfaces);
|
||||
|
||||
@ -1813,14 +1901,14 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).javadoc("Load data from another generated Record/POJO implementing the common interface %s", local);
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("def from(from : %s)", qualified);
|
||||
out.tab(1).println("def from(from : %s)", qualified);
|
||||
else
|
||||
out.tab(1).println("public void from(%s from);", qualified);
|
||||
|
||||
out.tab(1).javadoc("Copy data into another generated Record/POJO implementing the common interface %s", local);
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("def into [E <: %s](into : E) : E", qualified);
|
||||
out.tab(1).println("def into [E <: %s](into : E) : E", qualified);
|
||||
else
|
||||
out.tab(1).println("public <E extends %s> E into(E into);", qualified);
|
||||
}
|
||||
@ -2221,7 +2309,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printClassAnnotations(out, schema);
|
||||
|
||||
if (scala)
|
||||
out.println("object UDTs {");
|
||||
out.println("object UDTs {");
|
||||
else
|
||||
out.println("public class UDTs {");
|
||||
|
||||
@ -2233,7 +2321,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).javadoc("The type <code>%s</code>", udt.getQualifiedOutputName());
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("val %s = %s", id, fullId);
|
||||
out.tab(1).println("val %s = %s", id, fullId);
|
||||
else
|
||||
out.tab(1).println("public static %s %s = %s;", className, id, fullId);
|
||||
}
|
||||
@ -2811,7 +2899,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printClassAnnotations(out, schema);
|
||||
|
||||
if (scala)
|
||||
out.println("object Tables {");
|
||||
out.println("object Tables {");
|
||||
else
|
||||
out.println("public class Tables {");
|
||||
|
||||
@ -2832,9 +2920,9 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).javadoc(comment);
|
||||
|
||||
if (scala)
|
||||
out.tab(1).println("val %s = %s", id, fullId);
|
||||
out.tab(1).println("val %s = %s", id, fullId);
|
||||
else
|
||||
out.tab(1).println("public static final %s %s = %s;", className, id, fullId);
|
||||
out.tab(1).println("public static final %s %s = %s;", className, id, fullId);
|
||||
}
|
||||
|
||||
// [#3797] Table-valued functions generate two different literals in
|
||||
@ -2902,7 +2990,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (scala)
|
||||
tType = Record.class.getName() + keyColumns.size() + "[" + generics + "]";
|
||||
tType = Record.class.getName() + keyColumns.size() + "[" + generics + "]";
|
||||
else
|
||||
tType = Record.class.getName() + keyColumns.size() + "<" + generics + ">";
|
||||
}
|
||||
@ -2968,10 +3056,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (keyColumns.size() == 1) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("o.%s", getStrategy().getJavaGetterName(keyColumns.get(0), Mode.POJO));
|
||||
else
|
||||
out.tab(2).println("return object.%s();", getStrategy().getJavaGetterName(keyColumns.get(0), Mode.POJO));
|
||||
else
|
||||
out.tab(2).println("return object.%s();", getStrategy().getJavaGetterName(keyColumns.get(0), Mode.POJO));
|
||||
}
|
||||
|
||||
// [#2574] This should be replaced by a call to a method on the target table's Key type
|
||||
@ -2980,16 +3068,16 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
String separator = "";
|
||||
|
||||
for (ColumnDefinition column : keyColumns) {
|
||||
if (scala)
|
||||
params += separator + "o." + getStrategy().getJavaGetterName(column, Mode.POJO);
|
||||
else
|
||||
params += separator + "object." + getStrategy().getJavaGetterName(column, Mode.POJO) + "()";
|
||||
if (scala)
|
||||
params += separator + "o." + getStrategy().getJavaGetterName(column, Mode.POJO);
|
||||
else
|
||||
params += separator + "object." + getStrategy().getJavaGetterName(column, Mode.POJO) + "()";
|
||||
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
if (scala)
|
||||
out.tab(2).println("compositeKeyRecord(%s)", params);
|
||||
out.tab(2).println("compositeKeyRecord(%s)", params);
|
||||
else
|
||||
out.tab(2).println("return compositeKeyRecord(%s);", params);
|
||||
}
|
||||
@ -3653,18 +3741,16 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
private List<? extends TypedElementDefinition<? extends Definition>> getTypedElements(Definition definition) {
|
||||
if (definition instanceof TableDefinition) {
|
||||
if (definition instanceof TableDefinition)
|
||||
return ((TableDefinition) definition).getColumns();
|
||||
}
|
||||
else if (definition instanceof UDTDefinition) {
|
||||
else if (definition instanceof EmbeddableDefinition)
|
||||
return ((EmbeddableDefinition) definition).getColumns();
|
||||
else if (definition instanceof UDTDefinition)
|
||||
return ((UDTDefinition) definition).getAttributes();
|
||||
}
|
||||
else if (definition instanceof RoutineDefinition) {
|
||||
else if (definition instanceof RoutineDefinition)
|
||||
return ((RoutineDefinition) definition).getAllParameters();
|
||||
}
|
||||
else {
|
||||
else
|
||||
throw new IllegalArgumentException("Unsupported type : " + definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3761,7 +3847,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
else {
|
||||
out.println("public class %s extends %s<%s>[[before= implements ][%s]] {",
|
||||
className, TableImpl.class, recordType, interfaces);
|
||||
className, TableImpl.class, recordType, interfaces);
|
||||
out.printSerial();
|
||||
printSingletonInstance(out, table);
|
||||
}
|
||||
@ -3794,6 +3880,27 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// [#2530] Embeddable types
|
||||
for (EmbeddableDefinition embeddable : table.getEmbeddables()) {
|
||||
final String columnId = out.ref(getStrategy().getJavaIdentifier(embeddable), colRefSegments(null));
|
||||
final String columnType = out.ref(getStrategy().getFullJavaClassName(embeddable, Mode.RECORD));
|
||||
|
||||
final List<String> columnIds = new ArrayList<String>();
|
||||
for (EmbeddableColumnDefinition column : embeddable.getColumns())
|
||||
columnIds.add(out.ref(getStrategy().getJavaIdentifier(column), colRefSegments(column)));
|
||||
|
||||
out.tab(1).javadoc("The embeddable type <code>%s</code>.", embeddable.getOutputName());
|
||||
|
||||
if (scala) {
|
||||
out.tab(1).println("val %s : %s[%s, %s] = %s.createEmbeddable(%s.name(\"%s\"), classOf[%s], this, [[%s]])",
|
||||
columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, embeddable.getName(), columnType, columnIds);
|
||||
}
|
||||
else {
|
||||
out.tab(1).println("public final %s<%s, %s> %s = %s.createEmbeddable(%s.name(\"%s\"), %s.class, this, [[%s]]);",
|
||||
TableField.class, recordType, columnType, columnId, Internal.class, DSL.class, embeddable.getName(), columnType, columnIds);
|
||||
}
|
||||
}
|
||||
|
||||
if (scala) {
|
||||
out.tab(1).javadoc("Create a <code>%s</code> table reference", table.getQualifiedOutputName());
|
||||
out.tab(1).println("def this() = {");
|
||||
@ -4335,6 +4442,28 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
closeJavaWriter(out);
|
||||
}
|
||||
|
||||
protected void generateEmbeddables(SchemaDefinition schema) {
|
||||
log.info("Generating embeddables");
|
||||
|
||||
for (EmbeddableDefinition embeddable : database.getEmbeddables(schema)) {
|
||||
try {
|
||||
generateEmbeddable(schema, embeddable);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while generating embeddable " + embeddable, e);
|
||||
}
|
||||
}
|
||||
|
||||
watch.splitInfo("Tables generated");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void generateEmbeddable(SchemaDefinition schema, EmbeddableDefinition embeddable) {
|
||||
JavaWriter out = newJavaWriter(getFile(embeddable, Mode.RECORD));
|
||||
generateRecord0(embeddable, out);
|
||||
closeJavaWriter(out);
|
||||
}
|
||||
|
||||
private String converterTemplate(List<String> converter) {
|
||||
if (converter == null || converter.isEmpty())
|
||||
return "[[]]";
|
||||
@ -4644,7 +4773,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
String getter = getStrategy().getJavaGetterName(column, Mode.INTERFACE);
|
||||
|
||||
if (scala)
|
||||
out.tab(2).println("%s(from.%s)", setter, getter);
|
||||
out.tab(2).println("%s(from.%s)", setter, getter);
|
||||
else
|
||||
out.tab(2).println("%s(from.%s());", setter, getter);
|
||||
}
|
||||
@ -4653,7 +4782,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
if (generateInterfaces() && !generateImmutableInterfaces()) {
|
||||
if (scala) {
|
||||
out.tab(1).println("public <E extends %s> E into(E into) {", qualified);
|
||||
out.tab(1).println("public <E extends %s> E into(E into) {", qualified);
|
||||
out.tab(2).println("into.from(this)");
|
||||
out.tab(2).println("return into");
|
||||
out.tab(1).println("}");
|
||||
@ -4962,7 +5091,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printPackage(out, routine);
|
||||
|
||||
if (scala) {
|
||||
out.println("object %s {", className);
|
||||
out.println("object %s {", className);
|
||||
for (ParameterDefinition parameter : routine.getAllParameters()) {
|
||||
final String paramTypeFull = getJavaType(parameter.getType(resolver()));
|
||||
final String paramType = out.ref(paramTypeFull);
|
||||
@ -4997,7 +5126,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
else {
|
||||
out.println("public class %s extends %s<%s>[[before= implements ][%s]] {",
|
||||
className, AbstractRoutine.class, returnType, interfaces);
|
||||
className, AbstractRoutine.class, returnType, interfaces);
|
||||
out.printSerial();
|
||||
|
||||
for (ParameterDefinition parameter : routine.getAllParameters()) {
|
||||
@ -5022,7 +5151,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
|
||||
if (scala) {
|
||||
out.tab(1).println("{");
|
||||
out.tab(1).println("{");
|
||||
}
|
||||
else {
|
||||
out.tab(1).javadoc("Create a new routine call instance");
|
||||
@ -5039,30 +5168,30 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
final String paramId = getStrategy().getJavaIdentifier(parameter);
|
||||
|
||||
if (parameter.equals(routine.getReturnValue())) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("setReturnParameter(%s.%s)", className, paramId);
|
||||
else
|
||||
out.tab(2).println("setReturnParameter(%s);", paramId);
|
||||
else
|
||||
out.tab(2).println("setReturnParameter(%s);", paramId);
|
||||
}
|
||||
else if (routine.getInParameters().contains(parameter)) {
|
||||
if (routine.getOutParameters().contains(parameter)) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("addInOutParameter(%s.%s)", className, paramId);
|
||||
else
|
||||
out.tab(2).println("addInOutParameter(%s);", paramId);
|
||||
else
|
||||
out.tab(2).println("addInOutParameter(%s);", paramId);
|
||||
}
|
||||
else {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("addInParameter(%s.%s)", className, paramId);
|
||||
else
|
||||
out.tab(2).println("addInParameter(%s);", paramId);
|
||||
else
|
||||
out.tab(2).println("addInParameter(%s);", paramId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("addOutParameter(%s.%s)", className, paramId);
|
||||
else
|
||||
out.tab(2).println("addOutParameter(%s);", paramId);
|
||||
else
|
||||
out.tab(2).println("addOutParameter(%s);", paramId);
|
||||
}
|
||||
|
||||
|
||||
@ -5078,7 +5207,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (routine.getOverload() != null) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("setOverloaded(true)");
|
||||
else
|
||||
out.tab(2).println("setOverloaded(true);");
|
||||
@ -5106,7 +5235,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).javadoc("Set the <code>%s</code> parameter IN value to the routine", parameter.getOutputName());
|
||||
|
||||
if (scala) {
|
||||
out.tab(1).println("def %s(%s : %s) : Unit = {", setter, paramName, refNumberType(out, parameter.getType(resolver())));
|
||||
out.tab(1).println("def %s(%s : %s) : Unit = {", setter, paramName, refNumberType(out, parameter.getType(resolver())));
|
||||
out.tab(2).println("set%s(%s.%s, %s)", numberValue, className, paramId, paramName);
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
@ -5208,7 +5337,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
if (scala)
|
||||
out.tab(1).print("def %s(",
|
||||
getStrategy().getJavaMethodName(function, Mode.DEFAULT));
|
||||
getStrategy().getJavaMethodName(function, Mode.DEFAULT));
|
||||
else
|
||||
out.tab(1).print("public static %s<%s> %s(",
|
||||
function.isAggregate() ? AggregateFunction.class : Field.class,
|
||||
@ -5220,7 +5349,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.print(separator);
|
||||
|
||||
if (scala) {
|
||||
out.print("%s : ", getStrategy().getJavaMemberName(parameter));
|
||||
out.print("%s : ", getStrategy().getJavaMemberName(parameter));
|
||||
|
||||
if (parametersAsField) {
|
||||
out.print("%s[%s]", Field.class, refExtendsNumberType(out, parameter.getType(resolver())));
|
||||
@ -5242,13 +5371,13 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (scala) {
|
||||
out.println(") : %s[%s] = {",
|
||||
out.println(") : %s[%s] = {",
|
||||
function.isAggregate() ? AggregateFunction.class : Field.class,
|
||||
functionType);
|
||||
out.tab(2).println("val %s = new %s", localVar, className);
|
||||
}
|
||||
else {
|
||||
out.println(") {");
|
||||
out.println(") {");
|
||||
out.tab(2).println("%s %s = new %s();", className, localVar, className);
|
||||
}
|
||||
|
||||
@ -5402,10 +5531,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
String glue = "";
|
||||
if (!instance) {
|
||||
if (scala)
|
||||
out.print("%s : %s", configurationArgument, Configuration.class);
|
||||
else
|
||||
out.print("%s %s", Configuration.class, configurationArgument);
|
||||
if (scala)
|
||||
out.print("%s : %s", configurationArgument, Configuration.class);
|
||||
else
|
||||
out.print("%s %s", Configuration.class, configurationArgument);
|
||||
|
||||
glue = ", ";
|
||||
}
|
||||
@ -5420,7 +5549,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
final String paramMember = getStrategy().getJavaMemberName(parameter);
|
||||
|
||||
if (scala)
|
||||
out.print("%s%s : %s", glue, paramMember, paramType);
|
||||
out.print("%s%s : %s", glue, paramMember, paramType);
|
||||
else
|
||||
out.print("%s%s %s", glue, paramType, paramMember);
|
||||
|
||||
@ -5428,7 +5557,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (scala) {
|
||||
out.println(") : %s = {", functionType);
|
||||
out.println(") : %s = {", functionType);
|
||||
out.tab(2).println("val %s = new %s()", localVar, className);
|
||||
}
|
||||
else {
|
||||
@ -5482,7 +5611,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).javadoc("Call <code>%s</code>", procedure.getQualifiedOutputName());
|
||||
|
||||
if (scala) {
|
||||
out.tab(1).print("def ");
|
||||
out.tab(1).print("def ");
|
||||
}
|
||||
else {
|
||||
out.tab(1).print("public ");
|
||||
@ -5508,10 +5637,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
String glue = "";
|
||||
if (!instance) {
|
||||
if (scala)
|
||||
out.print("%s : %s", configurationArgument, Configuration.class);
|
||||
else
|
||||
out.print("%s %s", Configuration.class, configurationArgument);
|
||||
if (scala)
|
||||
out.print("%s : %s", configurationArgument, Configuration.class);
|
||||
else
|
||||
out.print("%s %s", Configuration.class, configurationArgument);
|
||||
|
||||
glue = ", ";
|
||||
}
|
||||
@ -5594,24 +5723,24 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(2).println("from((%s) %s.%s());", columnTypeInterface, localVar, getter);
|
||||
}
|
||||
else {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("from(%s.%s)", localVar, getter);
|
||||
else
|
||||
out.tab(2).println("from(%s.%s());", localVar, getter);
|
||||
else
|
||||
out.tab(2).println("from(%s.%s());", localVar, getter);
|
||||
}
|
||||
}
|
||||
|
||||
if (outParams.size() == 1) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("return %s.%s", localVar, getter);
|
||||
else
|
||||
out.tab(2).println("return %s.%s();", localVar, getter);
|
||||
else
|
||||
out.tab(2).println("return %s.%s();", localVar, getter);
|
||||
}
|
||||
else if (outParams.size() > 1) {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(2).println("return %s", localVar);
|
||||
else
|
||||
out.tab(2).println("return %s;", localVar);
|
||||
else
|
||||
out.tab(2).println("return %s;", localVar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5780,10 +5909,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
boolean hasCatalogVersion = !StringUtils.isBlank(catalogVersions.get(catalog));
|
||||
boolean hasSchemaVersion = !StringUtils.isBlank(schemaVersions.get(schema));
|
||||
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(1).println("value = %s(", out.ref("scala.Array"));
|
||||
else
|
||||
out.tab(1).println("value = {");
|
||||
else
|
||||
out.tab(1).println("value = {");
|
||||
|
||||
out.tab(2).println("\"http://www.jooq.org\",");
|
||||
out.tab(2).println("\"jOOQ version:%s\"%s", Constants.VERSION, (hasCatalogVersion || hasSchemaVersion ? "," : ""));
|
||||
@ -5802,10 +5931,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).println("comments = \"This class is generated by jOOQ\"");
|
||||
}
|
||||
else {
|
||||
if (scala)
|
||||
if (scala)
|
||||
out.tab(1).println("value = %s(", out.ref("scala.Array"));
|
||||
else
|
||||
out.tab(1).println("value = {");
|
||||
else
|
||||
out.tab(1).println("value = {");
|
||||
|
||||
out.tab(2).println("\"http://www.jooq.org\",");
|
||||
out.tab(2).println("\"jOOQ version:%s\"", Constants.VERSION);
|
||||
|
||||
@ -173,6 +173,12 @@
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:Embeddables">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.Embeddables"/>
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:ForcedTypes">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.ForcedTypes"/>
|
||||
@ -191,6 +197,24 @@
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:Embeddable">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.Embeddable"/>
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:EmbeddableFields">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.EmbeddableFields"/>
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:EmbeddableField">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.EmbeddableField"/>
|
||||
|
||||
</bindings>
|
||||
|
||||
<bindings if-exists="true" scd="~tns:ForcedType">
|
||||
|
||||
<class ref="org.jooq.meta.jaxb.ForcedType"/>
|
||||
|
||||
@ -40,6 +40,7 @@ package org.jooq.meta;
|
||||
|
||||
import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.meta.AbstractTypedElementDefinition.customType;
|
||||
import static org.jooq.tools.StringUtils.defaultIfEmpty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
@ -76,6 +77,8 @@ import org.jooq.impl.DefaultExecuteListenerProvider;
|
||||
import org.jooq.impl.SQLDataType;
|
||||
import org.jooq.meta.jaxb.CatalogMappingType;
|
||||
import org.jooq.meta.jaxb.CustomType;
|
||||
import org.jooq.meta.jaxb.Embeddable;
|
||||
import org.jooq.meta.jaxb.EmbeddableField;
|
||||
import org.jooq.meta.jaxb.EnumType;
|
||||
import org.jooq.meta.jaxb.ForcedType;
|
||||
import org.jooq.meta.jaxb.ForcedTypeObjectType;
|
||||
@ -112,6 +115,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
private boolean includeExcludeColumns;
|
||||
private boolean includeInvisibleColumns = true;
|
||||
private boolean includeTables = true;
|
||||
private boolean includeEmbeddables = true;
|
||||
private boolean includeRoutines = true;
|
||||
private boolean includeTriggerRoutines = false;
|
||||
private boolean includePackages = true;
|
||||
@ -138,6 +142,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
private List<CustomType> configuredCustomTypes;
|
||||
private List<EnumType> configuredEnumTypes;
|
||||
private List<ForcedType> configuredForcedTypes;
|
||||
private List<Embeddable> configuredEmbeddables;
|
||||
private SchemaVersionProvider schemaVersionProvider;
|
||||
private CatalogVersionProvider catalogVersionProvider;
|
||||
private Comparator<Definition> orderProvider;
|
||||
@ -161,6 +166,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
private List<ForeignKeyDefinition> foreignKeys;
|
||||
private List<CheckConstraintDefinition> checkConstraints;
|
||||
private List<TableDefinition> tables;
|
||||
private List<EmbeddableDefinition> embeddables;
|
||||
private List<EnumDefinition> enums;
|
||||
private List<DomainDefinition> domains;
|
||||
private List<UDTDefinition> udts;
|
||||
@ -177,6 +183,8 @@ public abstract class AbstractDatabase implements Database {
|
||||
private transient Map<SchemaDefinition, List<ForeignKeyDefinition>> foreignKeysBySchema;
|
||||
private transient Map<SchemaDefinition, List<CheckConstraintDefinition>> checkConstraintsBySchema;
|
||||
private transient Map<SchemaDefinition, List<TableDefinition>> tablesBySchema;
|
||||
private transient Map<SchemaDefinition, List<EmbeddableDefinition>> embeddablesBySchema;
|
||||
private transient Map<TableDefinition, List<EmbeddableDefinition>> embeddablesByTable;
|
||||
private transient Map<SchemaDefinition, List<EnumDefinition>> enumsBySchema;
|
||||
private transient Map<SchemaDefinition, List<UDTDefinition>> udtsBySchema;
|
||||
private transient Map<SchemaDefinition, List<ArrayDefinition>> arraysBySchema;
|
||||
@ -357,6 +365,9 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
|
||||
final boolean matches(Pattern pattern, Definition definition) {
|
||||
if (pattern == null)
|
||||
return false;
|
||||
|
||||
if (!getRegexMatchesPartialQualification())
|
||||
return pattern.matcher(definition.getName()).matches()
|
||||
|| pattern.matcher(definition.getQualifiedName()).matches();
|
||||
@ -371,6 +382,9 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
|
||||
final Pattern pattern(String regex) {
|
||||
if (regex == null)
|
||||
return null;
|
||||
|
||||
Pattern pattern = patterns.get(regex);
|
||||
|
||||
if (pattern == null) {
|
||||
@ -766,6 +780,16 @@ public abstract class AbstractDatabase implements Database {
|
||||
this.includeTables = includeTables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean getIncludeEmbeddables() {
|
||||
return includeEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setIncludeEmbeddables(boolean includeEmbeddables) {
|
||||
this.includeEmbeddables = includeEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean getIncludeRoutines() {
|
||||
return includeRoutines;
|
||||
@ -1453,6 +1477,84 @@ public abstract class AbstractDatabase implements Database {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setConfiguredEmbeddables(List<Embeddable> configuredEmbeddables) {
|
||||
this.configuredEmbeddables = configuredEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Embeddable> getConfiguredEmbeddables() {
|
||||
if (configuredEmbeddables == null)
|
||||
configuredEmbeddables = new ArrayList<Embeddable>();
|
||||
|
||||
return configuredEmbeddables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables() {
|
||||
List<EmbeddableDefinition> result = new ArrayList<EmbeddableDefinition>();
|
||||
|
||||
for (SchemaDefinition schema : getSchemata()) {
|
||||
for (TableDefinition table : getTables(schema)) {
|
||||
for (Embeddable embeddable : getConfiguredEmbeddables()) {
|
||||
List<ColumnDefinition> columns = new ArrayList<ColumnDefinition>();
|
||||
List<String> names = new ArrayList<String>();
|
||||
|
||||
for (EmbeddableField embeddableField : embeddable.getFields()) {
|
||||
boolean matched = false;
|
||||
|
||||
for (ColumnDefinition column : table.getColumns())
|
||||
if (matches(pattern(embeddableField.getExpression()), column))
|
||||
if (matched)
|
||||
log.warn("EmbeddableField configuration matched several columns in table " + table + ": " + embeddableField);
|
||||
else
|
||||
matched = columns.add(column) && names.add(defaultIfEmpty(embeddableField.getName(), column.getName()));
|
||||
}
|
||||
|
||||
if (columns.size() == embeddable.getFields().size())
|
||||
result.add(new DefaultEmbeddableDefinition(embeddable.getName(), names, table, columns));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables(SchemaDefinition schema) {
|
||||
if (embeddables == null) {
|
||||
embeddables = new ArrayList<EmbeddableDefinition>();
|
||||
|
||||
if (getIncludeEmbeddables()) {
|
||||
try {
|
||||
List<EmbeddableDefinition> r = getEmbeddables();
|
||||
|
||||
embeddables = sort(r);
|
||||
// indexes = sort(filterExcludeInclude(r)); TODO Support include / exclude for indexes (and constraints!)
|
||||
log.info("Embeddables fetched", fetchedSize(r, embeddables));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while fetching embeddables", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
log.info("Embeddables excluded");
|
||||
}
|
||||
|
||||
if (embeddablesBySchema == null)
|
||||
embeddablesBySchema = new LinkedHashMap<SchemaDefinition, List<EmbeddableDefinition>>();
|
||||
|
||||
return filterSchema(embeddables, schema, embeddablesBySchema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables(TableDefinition table) {
|
||||
if (embeddablesByTable == null)
|
||||
embeddablesByTable = new LinkedHashMap<TableDefinition, List<EmbeddableDefinition>>();
|
||||
|
||||
return filterTable(getEmbeddables(table.getSchema()), table, embeddablesByTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final EnumDefinition getEnum(SchemaDefinition schema, String name) {
|
||||
return getEnum(schema, name, false);
|
||||
@ -1795,18 +1897,40 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
|
||||
protected final <T extends Definition> List<T> filterSchema(List<T> definitions, SchemaDefinition schema) {
|
||||
if (schema == null) {
|
||||
if (schema == null)
|
||||
return definitions;
|
||||
}
|
||||
else {
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
for (T definition : definitions)
|
||||
if (definition.getSchema().equals(schema))
|
||||
result.add(definition);
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
return result;
|
||||
for (T definition : definitions)
|
||||
if (definition.getSchema().equals(schema))
|
||||
result.add(definition);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected final <T extends TableElementDefinition> List<T> filterTable(List<T> definitions, TableDefinition table, Map<TableDefinition, List<T>> cache) {
|
||||
List<T> result = cache.get(table);
|
||||
|
||||
if (result == null) {
|
||||
result = filterTable(definitions, table);
|
||||
cache.put(table, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected final <T extends TableElementDefinition> List<T> filterTable(List<T> definitions, TableDefinition table) {
|
||||
if (table == null)
|
||||
return definitions;
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
for (T definition : definitions)
|
||||
if (definition.getTable().equals(table))
|
||||
result.add(definition);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -57,9 +57,9 @@ public abstract class AbstractTableDefinition
|
||||
extends AbstractElementContainerDefinition<ColumnDefinition>
|
||||
implements TableDefinition {
|
||||
|
||||
private List<ParameterDefinition> parameters;
|
||||
private TableDefinition parentTable;
|
||||
private List<TableDefinition> childTables;
|
||||
private List<ParameterDefinition> parameters;
|
||||
private TableDefinition parentTable;
|
||||
private List<TableDefinition> childTables;
|
||||
|
||||
public AbstractTableDefinition(SchemaDefinition schema, String name, String comment) {
|
||||
super(schema, name, comment);
|
||||
@ -68,6 +68,11 @@ implements TableDefinition {
|
||||
this.childTables = new ArrayList<TableDefinition>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables() {
|
||||
return getDatabase().getEmbeddables(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UniqueKeyDefinition getPrimaryKey() {
|
||||
UniqueKeyDefinition primaryKey = null;
|
||||
|
||||
@ -49,6 +49,7 @@ import org.jooq.SQLDialect;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.meta.jaxb.CatalogMappingType;
|
||||
import org.jooq.meta.jaxb.CustomType;
|
||||
import org.jooq.meta.jaxb.Embeddable;
|
||||
import org.jooq.meta.jaxb.EnumType;
|
||||
import org.jooq.meta.jaxb.ForcedType;
|
||||
import org.jooq.meta.jaxb.RegexFlag;
|
||||
@ -151,6 +152,21 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
TableDefinition getTable(SchemaDefinition schema, Name name, boolean ignoreCase);
|
||||
|
||||
/**
|
||||
* Get all embeddables.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables();
|
||||
|
||||
/**
|
||||
* Get all embeddables for a given schema.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables(SchemaDefinition schema);
|
||||
|
||||
/**
|
||||
* Get all embeddables for a given table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables(TableDefinition table);
|
||||
|
||||
/**
|
||||
* The enum UDTs defined in this database.
|
||||
*/
|
||||
@ -511,6 +527,16 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
boolean getIncludeTables();
|
||||
|
||||
/**
|
||||
* Whether embeddable types should be included.
|
||||
*/
|
||||
void setIncludeEmbeddables(boolean includeEmbeddables);
|
||||
|
||||
/**
|
||||
* Whether embeddable types should be included.
|
||||
*/
|
||||
boolean getIncludeEmbeddables();
|
||||
|
||||
/**
|
||||
* Whether invisible columns should be included.
|
||||
*/
|
||||
@ -755,6 +781,17 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
ForcedType getConfiguredForcedType(Definition definition, DataTypeDefinition definedType);
|
||||
|
||||
/**
|
||||
* Configure the embeddable types.
|
||||
*/
|
||||
void setConfiguredEmbeddables(List<Embeddable> configuredEmbeddables);
|
||||
|
||||
/**
|
||||
* Get the configured embeddable type definitions for any given
|
||||
* {@link Definition}.
|
||||
*/
|
||||
List<Embeddable> getConfiguredEmbeddables();
|
||||
|
||||
/**
|
||||
* Get the dialect for this database.
|
||||
*/
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.meta;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultEmbeddableColumnDefinition
|
||||
extends AbstractTypedElementDefinition<EmbeddableDefinition>
|
||||
implements EmbeddableColumnDefinition {
|
||||
|
||||
private final ColumnDefinition column;
|
||||
private final int position;
|
||||
|
||||
public DefaultEmbeddableColumnDefinition(EmbeddableDefinition container, String name, ColumnDefinition column, int position) {
|
||||
super(container, name, position, column.getDefinedType(), column.getComment());
|
||||
|
||||
this.column = column;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ColumnDefinition getColumn() {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.meta;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultEmbeddableDefinition
|
||||
extends AbstractElementContainerDefinition<EmbeddableColumnDefinition>
|
||||
implements EmbeddableDefinition {
|
||||
|
||||
private final List<String> columnNames;
|
||||
private final TableDefinition table;
|
||||
private final List<EmbeddableColumnDefinition> embeddableColumns;
|
||||
|
||||
public DefaultEmbeddableDefinition(String name, List<String> columnNames, TableDefinition table, List<ColumnDefinition> columns) {
|
||||
super(table.getSchema(), name, "");
|
||||
|
||||
this.columnNames = columnNames;
|
||||
this.table = table;
|
||||
this.embeddableColumns = new ArrayList<EmbeddableColumnDefinition>();
|
||||
|
||||
for (int i = 0; i < columns.size(); i++)
|
||||
embeddableColumns.add(new DefaultEmbeddableColumnDefinition(this, columnNames.get(i), columns.get(i), i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableDefinition getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EmbeddableColumnDefinition> getElements0() throws SQLException {
|
||||
return embeddableColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableColumnDefinition> getColumns() {
|
||||
return getElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final EmbeddableColumnDefinition getColumn(String columnName) {
|
||||
return getElement(columnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final EmbeddableColumnDefinition getColumn(String columnName, boolean ignoreCase) {
|
||||
return getElement(columnName, ignoreCase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final EmbeddableColumnDefinition getColumn(int columnIndex) {
|
||||
return getElement(columnIndex);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq.meta;
|
||||
|
||||
/**
|
||||
* An interface defining a column of an embeddable type.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface EmbeddableColumnDefinition extends TypedElementDefinition<EmbeddableDefinition> {
|
||||
|
||||
/**
|
||||
* The column position in the embeddable type.
|
||||
*/
|
||||
int getPosition();
|
||||
|
||||
/**
|
||||
* The backing column definition.
|
||||
*/
|
||||
ColumnDefinition getColumn();
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq.meta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The definition of an embeddable type.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface EmbeddableDefinition extends TableElementDefinition {
|
||||
|
||||
/**
|
||||
* All columns in the type, table or view.
|
||||
*/
|
||||
List<EmbeddableColumnDefinition> getColumns();
|
||||
|
||||
/**
|
||||
* Get a column in this type by its name.
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(String columnName);
|
||||
|
||||
/**
|
||||
* Get a column in this type by its name.
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(String columnName, boolean ignoreCase);
|
||||
|
||||
/**
|
||||
* Get a column in this type by its index (starting at 0).
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(int columnIndex);
|
||||
|
||||
}
|
||||
@ -44,12 +44,7 @@ import java.util.List;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface IndexDefinition extends Definition {
|
||||
|
||||
/**
|
||||
* The table holding this index.
|
||||
*/
|
||||
TableDefinition getTable();
|
||||
public interface IndexDefinition extends TableElementDefinition {
|
||||
|
||||
/**
|
||||
* The list of columns making up the index.
|
||||
|
||||
@ -70,6 +70,11 @@ public interface TableDefinition extends Definition {
|
||||
*/
|
||||
ColumnDefinition getColumn(int columnIndex);
|
||||
|
||||
/**
|
||||
* All embeddable types in the table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables();
|
||||
|
||||
/**
|
||||
* Get the indexes for this table.
|
||||
*/
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq.meta;
|
||||
|
||||
/**
|
||||
* The definition of an object that is contained in a table.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface TableElementDefinition extends Definition {
|
||||
|
||||
/**
|
||||
* The table that this object is part of.
|
||||
*/
|
||||
TableDefinition getTable();
|
||||
|
||||
}
|
||||
@ -57,6 +57,8 @@ public class Database implements Serializable
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean includeTables = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean includeEmbeddables = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean includeRoutines = true;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean includeTriggerRoutines = false;
|
||||
@ -140,6 +142,9 @@ public class Database implements Serializable
|
||||
@XmlElementWrapper(name = "schemata")
|
||||
@XmlElement(name = "schema")
|
||||
protected List<SchemaMappingType> schemata;
|
||||
@XmlElementWrapper(name = "embeddables")
|
||||
@XmlElement(name = "embeddable")
|
||||
protected List<Embeddable> embeddables;
|
||||
@XmlElementWrapper(name = "customTypes")
|
||||
@XmlElement(name = "customType")
|
||||
protected List<CustomType> customTypes;
|
||||
@ -379,6 +384,30 @@ public class Database implements Serializable
|
||||
this.includeTables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This flag indicates whether embeddable types should be included in output produced by this database
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isIncludeEmbeddables() {
|
||||
return includeEmbeddables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the includeEmbeddables property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setIncludeEmbeddables(Boolean value) {
|
||||
this.includeEmbeddables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This flag indicates whether routines should be included in output produced by this database
|
||||
*
|
||||
@ -1299,6 +1328,17 @@ public class Database implements Serializable
|
||||
this.schemata = schemata;
|
||||
}
|
||||
|
||||
public List<Embeddable> getEmbeddables() {
|
||||
if (embeddables == null) {
|
||||
embeddables = new ArrayList<Embeddable>();
|
||||
}
|
||||
return embeddables;
|
||||
}
|
||||
|
||||
public void setEmbeddables(List<Embeddable> embeddables) {
|
||||
this.embeddables = embeddables;
|
||||
}
|
||||
|
||||
public List<CustomType> getCustomTypes() {
|
||||
if (customTypes == null) {
|
||||
customTypes = new ArrayList<CustomType>();
|
||||
@ -1378,6 +1418,11 @@ public class Database implements Serializable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withIncludeEmbeddables(Boolean value) {
|
||||
setIncludeEmbeddables(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withIncludeRoutines(Boolean value) {
|
||||
setIncludeRoutines(value);
|
||||
return this;
|
||||
@ -1606,6 +1651,27 @@ public class Database implements Serializable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withEmbeddables(Embeddable... values) {
|
||||
if (values!= null) {
|
||||
for (Embeddable value: values) {
|
||||
getEmbeddables().add(value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withEmbeddables(Collection<Embeddable> values) {
|
||||
if (values!= null) {
|
||||
getEmbeddables().addAll(values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withEmbeddables(List<Embeddable> embeddables) {
|
||||
setEmbeddables(embeddables);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withCustomTypes(CustomType... values) {
|
||||
if (values!= null) {
|
||||
for (CustomType value: values) {
|
||||
@ -1711,6 +1777,11 @@ public class Database implements Serializable
|
||||
sb.append(includeTables);
|
||||
sb.append("</includeTables>");
|
||||
}
|
||||
if (includeEmbeddables!= null) {
|
||||
sb.append("<includeEmbeddables>");
|
||||
sb.append(includeEmbeddables);
|
||||
sb.append("</includeEmbeddables>");
|
||||
}
|
||||
if (includeRoutines!= null) {
|
||||
sb.append("<includeRoutines>");
|
||||
sb.append(includeRoutines);
|
||||
@ -1903,6 +1974,15 @@ public class Database implements Serializable
|
||||
}
|
||||
sb.append("</schemata>");
|
||||
}
|
||||
if (embeddables!= null) {
|
||||
sb.append("<embeddables>");
|
||||
for (int i = 0; (i<embeddables.size()); i ++) {
|
||||
sb.append("<embeddable>");
|
||||
sb.append(embeddables.get(i));
|
||||
sb.append("</embeddable>");
|
||||
}
|
||||
sb.append("</embeddables>");
|
||||
}
|
||||
if (customTypes!= null) {
|
||||
sb.append("<customTypes>");
|
||||
for (int i = 0; (i<customTypes.size()); i ++) {
|
||||
@ -2008,6 +2088,15 @@ public class Database implements Serializable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (includeEmbeddables == null) {
|
||||
if (other.includeEmbeddables!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!includeEmbeddables.equals(other.includeEmbeddables)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (includeRoutines == null) {
|
||||
if (other.includeRoutines!= null) {
|
||||
return false;
|
||||
@ -2332,6 +2421,15 @@ public class Database implements Serializable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (embeddables == null) {
|
||||
if (other.embeddables!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!embeddables.equals(other.embeddables)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (customTypes == null) {
|
||||
if (other.customTypes!= null) {
|
||||
return false;
|
||||
@ -2373,6 +2471,7 @@ public class Database implements Serializable
|
||||
result = ((prime*result)+((excludes == null)? 0 :excludes.hashCode()));
|
||||
result = ((prime*result)+((includeExcludeColumns == null)? 0 :includeExcludeColumns.hashCode()));
|
||||
result = ((prime*result)+((includeTables == null)? 0 :includeTables.hashCode()));
|
||||
result = ((prime*result)+((includeEmbeddables == null)? 0 :includeEmbeddables.hashCode()));
|
||||
result = ((prime*result)+((includeRoutines == null)? 0 :includeRoutines.hashCode()));
|
||||
result = ((prime*result)+((includeTriggerRoutines == null)? 0 :includeTriggerRoutines.hashCode()));
|
||||
result = ((prime*result)+((includePackages == null)? 0 :includePackages.hashCode()));
|
||||
@ -2409,6 +2508,7 @@ public class Database implements Serializable
|
||||
result = ((prime*result)+((properties == null)? 0 :properties.hashCode()));
|
||||
result = ((prime*result)+((catalogs == null)? 0 :catalogs.hashCode()));
|
||||
result = ((prime*result)+((schemata == null)? 0 :schemata.hashCode()));
|
||||
result = ((prime*result)+((embeddables == null)? 0 :embeddables.hashCode()));
|
||||
result = ((prime*result)+((customTypes == null)? 0 :customTypes.hashCode()));
|
||||
result = ((prime*result)+((enumTypes == null)? 0 :enumTypes.hashCode()));
|
||||
result = ((prime*result)+((forcedTypes == null)? 0 :forcedTypes.hashCode()));
|
||||
|
||||
170
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Embeddable.java
Normal file
170
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Embeddable.java
Normal file
@ -0,0 +1,170 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
package org.jooq.meta.jaxb;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import org.jooq.util.jaxb.tools.StringAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* An embeddable type declaration
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "Embeddable", propOrder = {
|
||||
|
||||
})
|
||||
@SuppressWarnings({
|
||||
"all"
|
||||
})
|
||||
public class Embeddable implements Serializable
|
||||
{
|
||||
|
||||
private final static long serialVersionUID = 31200L;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String name;
|
||||
@XmlElementWrapper(name = "fields")
|
||||
@XmlElement(name = "field")
|
||||
protected List<EmbeddableField> fields;
|
||||
|
||||
/**
|
||||
* The name of the embeddable type
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
public List<EmbeddableField> getFields() {
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<EmbeddableField>();
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setFields(List<EmbeddableField> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public Embeddable withName(String value) {
|
||||
setName(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Embeddable withFields(EmbeddableField... values) {
|
||||
if (values!= null) {
|
||||
for (EmbeddableField value: values) {
|
||||
getFields().add(value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Embeddable withFields(Collection<EmbeddableField> values) {
|
||||
if (values!= null) {
|
||||
getFields().addAll(values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Embeddable withFields(List<EmbeddableField> fields) {
|
||||
setFields(fields);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (name!= null) {
|
||||
sb.append("<name>");
|
||||
sb.append(name);
|
||||
sb.append("</name>");
|
||||
}
|
||||
if (fields!= null) {
|
||||
sb.append("<fields>");
|
||||
for (int i = 0; (i<fields.size()); i ++) {
|
||||
sb.append("<field>");
|
||||
sb.append(fields.get(i));
|
||||
sb.append("</field>");
|
||||
}
|
||||
sb.append("</fields>");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass()!= that.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Embeddable other = ((Embeddable) that);
|
||||
if (name == null) {
|
||||
if (other.name!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (fields == null) {
|
||||
if (other.fields!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!fields.equals(other.fields)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = ((prime*result)+((name == null)? 0 :name.hashCode()));
|
||||
result = ((prime*result)+((fields == null)? 0 :fields.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
173
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/EmbeddableField.java
Normal file
173
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/EmbeddableField.java
Normal file
@ -0,0 +1,173 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
package org.jooq.meta.jaxb;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import org.jooq.util.jaxb.tools.StringAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for EmbeddableField complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="EmbeddableField">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <all>
|
||||
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
|
||||
* <element name="expression" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* </all>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "EmbeddableField", propOrder = {
|
||||
|
||||
})
|
||||
@SuppressWarnings({
|
||||
"all"
|
||||
})
|
||||
public class EmbeddableField implements Serializable
|
||||
{
|
||||
|
||||
private final static long serialVersionUID = 31200L;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String name;
|
||||
@XmlElement(required = true)
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String expression;
|
||||
|
||||
/**
|
||||
* A name for the field in case the regex does not produce unique names for all matches.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A regex matching all column names that are part of the embeddable type. The regex must match only one column per table.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the expression property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setExpression(String value) {
|
||||
this.expression = value;
|
||||
}
|
||||
|
||||
public EmbeddableField withName(String value) {
|
||||
setName(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbeddableField withExpression(String value) {
|
||||
setExpression(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (name!= null) {
|
||||
sb.append("<name>");
|
||||
sb.append(name);
|
||||
sb.append("</name>");
|
||||
}
|
||||
if (expression!= null) {
|
||||
sb.append("<expression>");
|
||||
sb.append(expression);
|
||||
sb.append("</expression>");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass()!= that.getClass()) {
|
||||
return false;
|
||||
}
|
||||
EmbeddableField other = ((EmbeddableField) that);
|
||||
if (name == null) {
|
||||
if (other.name!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!name.equals(other.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (expression == null) {
|
||||
if (other.expression!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!expression.equals(other.expression)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = ((prime*result)+((name == null)? 0 :name.hashCode()));
|
||||
result = ((prime*result)+((expression == null)? 0 :expression.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -67,6 +67,8 @@ public class Generate implements Serializable
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean tables = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean embeddables = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean records = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean recordsImplementingRecordN = true;
|
||||
@ -534,6 +536,30 @@ public class Generate implements Serializable
|
||||
this.tables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate embeddable classes.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isEmbeddables() {
|
||||
return embeddables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the embeddables property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setEmbeddables(Boolean value) {
|
||||
this.embeddables = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate TableRecord classes.
|
||||
*
|
||||
@ -1835,6 +1861,11 @@ public class Generate implements Serializable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withEmbeddables(Boolean value) {
|
||||
setEmbeddables(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withRecords(Boolean value) {
|
||||
setRecords(value);
|
||||
return this;
|
||||
@ -2163,6 +2194,11 @@ public class Generate implements Serializable
|
||||
sb.append(tables);
|
||||
sb.append("</tables>");
|
||||
}
|
||||
if (embeddables!= null) {
|
||||
sb.append("<embeddables>");
|
||||
sb.append(embeddables);
|
||||
sb.append("</embeddables>");
|
||||
}
|
||||
if (records!= null) {
|
||||
sb.append("<records>");
|
||||
sb.append(records);
|
||||
@ -2563,6 +2599,15 @@ public class Generate implements Serializable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (embeddables == null) {
|
||||
if (other.embeddables!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!embeddables.equals(other.embeddables)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (records == null) {
|
||||
if (other.records!= null) {
|
||||
return false;
|
||||
@ -3035,6 +3080,7 @@ public class Generate implements Serializable
|
||||
result = ((prime*result)+((links == null)? 0 :links.hashCode()));
|
||||
result = ((prime*result)+((keys == null)? 0 :keys.hashCode()));
|
||||
result = ((prime*result)+((tables == null)? 0 :tables.hashCode()));
|
||||
result = ((prime*result)+((embeddables == null)? 0 :embeddables.hashCode()));
|
||||
result = ((prime*result)+((records == null)? 0 :records.hashCode()));
|
||||
result = ((prime*result)+((recordsImplementingRecordN == null)? 0 :recordsImplementingRecordN.hashCode()));
|
||||
result = ((prime*result)+((pojos == null)? 0 :pojos.hashCode()));
|
||||
|
||||
@ -180,6 +180,22 @@ public class ObjectFactory {
|
||||
return new EnumType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Embeddable }
|
||||
*
|
||||
*/
|
||||
public Embeddable createEmbeddable() {
|
||||
return new Embeddable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link EmbeddableField }
|
||||
*
|
||||
*/
|
||||
public EmbeddableField createEmbeddableField() {
|
||||
return new EmbeddableField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ForcedType }
|
||||
*
|
||||
|
||||
@ -471,6 +471,10 @@ Excludes match before includes, i.e. excludes have a higher priority.]]></jxb:ja
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This flag indicates whether tables should be included in output produced by this database]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="includeEmbeddables" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This flag indicates whether embeddable types should be included in output produced by this database]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="includeRoutines" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This flag indicates whether routines should be included in output produced by this database]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
@ -695,6 +699,10 @@ generated artefacts.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
This comparator can be used to influence the order of any object that is produced by jOOQ meta, and thus, indirectly, the order of declared objects in generated code.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="embeddables" type="tns:Embeddables" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Configure embeddable types.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="customTypes" type="tns:CustomTypes" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[@deprecated Use {@link #getForcedTypes()} only]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
@ -791,6 +799,12 @@ for Oracle.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="Embeddables">
|
||||
<sequence>
|
||||
<element name="embeddable" type="tns:Embeddable" minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ForcedTypes">
|
||||
<sequence>
|
||||
<element name="forcedType" type="tns:ForcedType" minOccurs="0" maxOccurs="unbounded" />
|
||||
@ -829,6 +843,38 @@ for Oracle.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<complexType name="Embeddable">
|
||||
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[An embeddable type declaration]]></jxb:javadoc></jxb:class></appinfo></annotation>
|
||||
<all>
|
||||
<element name="name" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The name of the embeddable type]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="fields" type="tns:EmbeddableFields" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A set of field specifications for the embeddable type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<complexType name="EmbeddableFields">
|
||||
<sequence>
|
||||
<element name="field" type="tns:EmbeddableField" minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="EmbeddableField">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A field specification for an embeddable type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<all>
|
||||
<element name="name" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A name for the field in case the regex does not produce unique names for all matches.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="expression" type="string" minOccurs="1" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A regex matching all column names that are part of the embeddable type. The regex must match only one column per table.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ForcedType">
|
||||
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[A forced type declaration]]></jxb:javadoc></jxb:class></appinfo></annotation>
|
||||
<all>
|
||||
@ -959,6 +1005,10 @@ jOOQ version used for source code.]]></jxb:javadoc></jxb:property></appinfo></an
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate Table classes.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="embeddables" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate embeddable classes.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="records" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate TableRecord classes.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
65
jOOQ/src/main/java/org/jooq/EmbeddableRecord.java
Normal file
65
jOOQ/src/main/java/org/jooq/EmbeddableRecord.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
/**
|
||||
* A record originating from a single table
|
||||
*
|
||||
* @param <R> The embeddable record type
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface EmbeddableRecord<R extends EmbeddableRecord<R>> extends Record {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
R original();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
<T> R with(Field<T> field, T value);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
<T, U> R with(Field<T> field, U value, Converter<? extends T, ? super U> converter);
|
||||
}
|
||||
@ -1460,32 +1460,26 @@ abstract class AbstractField<T> extends AbstractNamed implements Field<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final <Z extends Number> Field<Z> numeric() {
|
||||
if (getDataType().isNumeric()) {
|
||||
if (getDataType().isNumeric())
|
||||
return (Field<Z>) this;
|
||||
}
|
||||
else {
|
||||
else
|
||||
return (Field<Z>) cast(BigDecimal.class);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Field<String> varchar() {
|
||||
if (getDataType().isString()) {
|
||||
if (getDataType().isString())
|
||||
return (Field<String>) this;
|
||||
}
|
||||
else {
|
||||
else
|
||||
return cast(String.class);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final <Z extends java.util.Date> Field<Z> date() {
|
||||
if (getDataType().isTemporal()) {
|
||||
if (getDataType().isTemporal())
|
||||
return (Field<Z>) this;
|
||||
}
|
||||
else {
|
||||
else
|
||||
return (Field<Z>) cast(Timestamp.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,7 +40,9 @@ package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.conf.SettingsTools.updatablePrimaryKeys;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
import static org.jooq.impl.Tools.resetChangedOnNotNull;
|
||||
import static org.jooq.impl.Tools.settings;
|
||||
import static org.jooq.impl.Tools.ThreadGuard.Guard.RECORD_TOSTRING;
|
||||
@ -62,6 +64,7 @@ import org.jooq.CSVFormat;
|
||||
import org.jooq.ChartFormat;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSONFormat;
|
||||
import org.jooq.Name;
|
||||
@ -240,7 +243,16 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
|
||||
@Override
|
||||
public final <T> T get(Field<T> field) {
|
||||
return (T) get(indexOrFail(fieldsRow(), field));
|
||||
if (field instanceof EmbeddableTableField) {
|
||||
Field<?>[] f = embeddedFields(field);
|
||||
|
||||
return (T) Tools
|
||||
.newRecord(fetched, ((EmbeddableTableField<?, ?>) field).recordType)
|
||||
.operate(new TransferRecordState<Record>(f));
|
||||
}
|
||||
else {
|
||||
return (T) get(indexOrFail(fieldsRow(), field));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -310,15 +322,24 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
}
|
||||
|
||||
protected final void set(int index, Object value) {
|
||||
set(index, (Field) field(index), value);
|
||||
set(index, field(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> void set(Field<T> field, T value) {
|
||||
set(indexOrFail(fields, field), field, value);
|
||||
if (isEmbeddable(field) && value instanceof EmbeddableRecord) {
|
||||
Field<?>[] f = embeddedFields(field);
|
||||
Object[] v = ((EmbeddableRecord) value).intoArray();
|
||||
|
||||
for (int i = 0; i < f.length; i++)
|
||||
set(indexOrFail(fields, f[i]), f[i], v[i]);
|
||||
}
|
||||
else {
|
||||
set(indexOrFail(fields, field), field, value);
|
||||
}
|
||||
}
|
||||
|
||||
final <T> void set(int index, Field<T> field, T value) {
|
||||
final void set(int index, Field<?> field, Object value) {
|
||||
// Relevant issues documenting this method's behaviour:
|
||||
// [#945] Avoid bugs resulting from setting the same value twice
|
||||
// [#948] To allow for controlling the number of hard-parses
|
||||
|
||||
@ -55,10 +55,13 @@ import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
import static org.jooq.conf.ParamType.INLINED;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.Keywords.K_AS;
|
||||
import static org.jooq.impl.Keywords.K_CAST;
|
||||
import static org.jooq.impl.Keywords.K_ESCAPE;
|
||||
import static org.jooq.impl.Keywords.K_VARCHAR;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.isEmbeddable;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
@ -99,6 +102,13 @@ final class CompareCondition extends AbstractCondition implements LikeEscapeStep
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (isEmbeddable(field1) && isEmbeddable(field2))
|
||||
ctx.visit(row(embeddedFields(field1)).compare(comparator, embeddedFields(field2)));
|
||||
else
|
||||
accept0(ctx);
|
||||
}
|
||||
|
||||
private final void accept0(Context<?> ctx) {
|
||||
SQLDialect family = ctx.family();
|
||||
Field<?> lhs = field1;
|
||||
Field<?> rhs = field2;
|
||||
|
||||
97
jOOQ/src/main/java/org/jooq/impl/EmbeddableRecordImpl.java
Normal file
97
jOOQ/src/main/java/org/jooq/impl/EmbeddableRecordImpl.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Row;
|
||||
|
||||
/**
|
||||
* A record implementation for a record originating from a single table
|
||||
* <p>
|
||||
* This type is for JOOQ INTERNAL USE only. Do not reference directly
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class EmbeddableRecordImpl<R extends EmbeddableRecord<R>> extends AbstractRecord implements EmbeddableRecord<R> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -1260149220986944763L;
|
||||
|
||||
public EmbeddableRecordImpl(Field<?>... fields) {
|
||||
super(fields);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T> R with(Field<T> field, T value) {
|
||||
return (R) super.with(field, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T, U> R with(Field<T> field, U value, Converter<? extends T, ? super U> converter) {
|
||||
return (R) super.with(field, value, converter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Subclasses may override this method
|
||||
*/
|
||||
@Override
|
||||
public Row fieldsRow() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subclasses may override this method
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public Row valuesRow() {
|
||||
return new RowImpl(Tools.fields(intoArray(), fields.fields.fields()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final R original() {
|
||||
return (R) super.original();
|
||||
}
|
||||
}
|
||||
87
jOOQ/src/main/java/org/jooq/impl/EmbeddableTableField.java
Normal file
87
jOOQ/src/main/java/org/jooq/impl/EmbeddableTableField.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class EmbeddableTableField<R extends Record, T extends Record> extends AbstractField<T> implements TableField<R, T> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -7105430856294526440L;
|
||||
final Table<R> table;
|
||||
final TableField<R, ?>[] fields;
|
||||
final Class<T> recordType;
|
||||
|
||||
EmbeddableTableField(Name name, Class<T> recordType, Table<R> table, TableField<R, ?>[] fields) {
|
||||
super(name, new DefaultDataType<T>(SQLDialect.DEFAULT, recordType, name.last()));
|
||||
|
||||
this.table = table;
|
||||
this.recordType = recordType;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// TableField API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
Object previous = ctx.data(DATA_LIST_ALREADY_INDENTED);
|
||||
|
||||
ctx.data(DATA_LIST_ALREADY_INDENTED, true);
|
||||
ctx.visit(new QueryPartList<TableField<?, ?>>(fields));
|
||||
ctx.data(DATA_LIST_ALREADY_INDENTED, previous);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<R> getTable() {
|
||||
return table;
|
||||
}
|
||||
}
|
||||
@ -43,6 +43,7 @@ import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.impl.Tools.flattenEntrySet;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
@ -87,12 +88,11 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
boolean restoreQualify = ctx.qualify();
|
||||
boolean supportsQualify = NO_SUPPORT_QUALIFY.contains(ctx.family()) ? false : restoreQualify;
|
||||
|
||||
for (Entry<Field<?>, Field<?>> entry : entrySet()) {
|
||||
for (Entry<Field<?>, Field<?>> entry : flattenEntrySet(entrySet())) {
|
||||
ctx.sql(separator);
|
||||
|
||||
if (!"".equals(separator)) {
|
||||
if (!"".equals(separator))
|
||||
ctx.formatNewLine();
|
||||
}
|
||||
|
||||
ctx.start(assignmentClause)
|
||||
.qualify(supportsQualify)
|
||||
|
||||
@ -61,6 +61,13 @@ import org.jooq.UniqueKey;
|
||||
*/
|
||||
public final class Internal {
|
||||
|
||||
/**
|
||||
* Factory method for embeddable types.
|
||||
*/
|
||||
public static final <R extends Record, T extends Record> TableField<R, T> createEmbeddable(Name name, Class<T> recordType, Table<R> table, TableField<R, ?>... fields) {
|
||||
return new EmbeddableTableField<R, T>(name, recordType, table, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for indexes.
|
||||
*/
|
||||
|
||||
@ -133,34 +133,39 @@ final class SortFieldImpl<T> extends AbstractQueryPart implements SortField<T> {
|
||||
ctx.visit(nvl2(field, ifNotNull, ifNull))
|
||||
.sql(", ");
|
||||
|
||||
acceptFieldAndOrder(ctx);
|
||||
|
||||
acceptFieldAndOrder(ctx, false);
|
||||
break;
|
||||
}
|
||||
|
||||
// DERBY, H2, HSQLDB, ORACLE, POSTGRES
|
||||
default: {
|
||||
acceptFieldAndOrder(ctx);
|
||||
|
||||
if (nullsFirst)
|
||||
ctx.sql(' ').visit(K_NULLS_FIRST);
|
||||
else
|
||||
ctx.sql(' ').visit(K_NULLS_LAST);
|
||||
|
||||
acceptFieldAndOrder(ctx, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
acceptFieldAndOrder(ctx);
|
||||
acceptFieldAndOrder(ctx, false);
|
||||
}
|
||||
}
|
||||
|
||||
private final void acceptFieldAndOrder(Context<?> ctx) {
|
||||
ctx.visit(field);
|
||||
private final void acceptFieldAndOrder(Context<?> ctx, boolean includeNulls) {
|
||||
String separator = "";
|
||||
|
||||
if (order != SortOrder.DEFAULT)
|
||||
ctx.sql(' ')
|
||||
.visit(order.toKeyword());
|
||||
for (Field<?> f : Tools.flatten(field)) {
|
||||
ctx.sql(separator).visit(f);
|
||||
|
||||
if (order != SortOrder.DEFAULT)
|
||||
ctx.sql(' ')
|
||||
.visit(order.toKeyword());
|
||||
|
||||
if (includeNulls)
|
||||
if (nullsFirst)
|
||||
ctx.sql(' ').visit(K_NULLS_FIRST);
|
||||
else
|
||||
ctx.sql(' ').visit(K_NULLS_LAST);
|
||||
|
||||
separator = ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ package org.jooq.impl;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static java.lang.Character.isJavaIdentifierPart;
|
||||
import static java.util.Collections.singletonList;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
@ -166,6 +167,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@ -176,6 +178,8 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -201,6 +205,7 @@ import org.jooq.Context;
|
||||
import org.jooq.Cursor;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.EnumType;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteListener;
|
||||
@ -4772,4 +4777,164 @@ final class Tools {
|
||||
static final boolean isEmpty(Object[] array) {
|
||||
return array == null || array.length == 0;
|
||||
}
|
||||
|
||||
static final boolean isEmbeddable(Object object) {
|
||||
return object instanceof EmbeddableTableField
|
||||
|| object instanceof Val && ((Val<?>) object).value instanceof EmbeddableRecord
|
||||
|| object instanceof EmbeddableRecord;
|
||||
}
|
||||
|
||||
static final Field<?>[] embeddedFields(Object object) {
|
||||
return object instanceof EmbeddableTableField
|
||||
? ((EmbeddableTableField<?, ?>) object).fields
|
||||
: object instanceof Val && ((Val<?>) object).value instanceof EmbeddableRecord
|
||||
? ((EmbeddableRecord<?>) ((Val<?>) object).value).valuesRow().fields()
|
||||
: object instanceof EmbeddableRecord
|
||||
? ((EmbeddableRecord<?>) object).valuesRow().fields()
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten out an {@link EmbeddableTableField}.
|
||||
*/
|
||||
static final <E extends Field<?>> Iterable<E> flatten(final E field) {
|
||||
return new Iterable<E>() {
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
Iterator<E> it = singletonList(field).iterator();
|
||||
|
||||
if (field instanceof EmbeddableTableField)
|
||||
return new FlatteningIterator<E>(it) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
List<E> flatten(E e) {
|
||||
return (List<E>) Arrays.asList(((EmbeddableTableField<?, ?>) e).fields);
|
||||
}
|
||||
};
|
||||
else
|
||||
return it;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten out {@link EmbeddableTableField} elements contained in an
|
||||
* ordinary iterable.
|
||||
*/
|
||||
static final <E extends Field<?>> Iterable<E> flattenCollection(final Iterable<E> iterable) {
|
||||
return new Iterable<E>() {
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new FlatteningIterator<E>(iterable.iterator()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
List<E> flatten(E e) {
|
||||
if (e instanceof EmbeddableTableField)
|
||||
return (List<E>) Arrays.asList(((EmbeddableTableField<?, ?>) e).fields);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten out {@link EmbeddableTableField} elements contained in an
|
||||
* entry set iterable.
|
||||
*/
|
||||
static final <E extends Entry<Field<?>, Field<?>>> Iterable<E> flattenEntrySet(final Iterable<E> iterable) {
|
||||
return new Iterable<E>() {
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new FlatteningIterator<E>(iterable.iterator()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
List<E> flatten(E e) {
|
||||
if (e.getKey() instanceof EmbeddableTableField) {
|
||||
List<E> result = new ArrayList<E>();
|
||||
Field<?>[] keys = embeddedFields(e.getKey());
|
||||
Field<?>[] values = embeddedFields(e.getValue());
|
||||
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
result.add((E) new SimpleImmutableEntry<Field<?>, Field<?>>(
|
||||
keys[i], values[i]
|
||||
));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A base implementation for {@link EmbeddableTableField} flattening
|
||||
* iterators with a default implementation for {@link Iterator#remove()} for
|
||||
* convenience in the Java 6 build.
|
||||
*/
|
||||
static abstract class FlatteningIterator<E> implements Iterator<E> {
|
||||
private final Iterator<E> delegate;
|
||||
private Iterator<E> flatten;
|
||||
private E next;
|
||||
|
||||
FlatteningIterator(Iterator<E> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
abstract List<E> flatten(E e);
|
||||
|
||||
private final void move() {
|
||||
if (next == null) {
|
||||
if (flatten != null) {
|
||||
if (flatten.hasNext()) {
|
||||
next = flatten.next();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
flatten = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (delegate.hasNext()) {
|
||||
next = delegate.next();
|
||||
|
||||
List<E> flattened = flatten(next);
|
||||
if (flattened == null)
|
||||
return;
|
||||
|
||||
next = null;
|
||||
flatten = flattened.iterator();
|
||||
move();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
move();
|
||||
return next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final E next() {
|
||||
move();
|
||||
|
||||
if (next == null)
|
||||
throw new NoSuchElementException();
|
||||
|
||||
E result = next;
|
||||
next = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void remove() {
|
||||
throw new UnsupportedOperationException("remove");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,11 +39,15 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.conf.ParamType.NAMED;
|
||||
import static org.jooq.conf.ParamType.NAMED_OR_INLINED;
|
||||
import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
@ -70,7 +74,14 @@ final class Val<T> extends AbstractParam<T> {
|
||||
|
||||
@Override
|
||||
public void accept(Context<?> ctx) {
|
||||
if (ctx instanceof RenderContext) {
|
||||
if (value instanceof EmbeddableRecord) {
|
||||
Object previous = ctx.data(DATA_LIST_ALREADY_INDENTED);
|
||||
|
||||
ctx.data(DATA_LIST_ALREADY_INDENTED, true);
|
||||
ctx.visit(new QueryPartList<Field<?>>(embeddedFields(this)));
|
||||
ctx.data(DATA_LIST_ALREADY_INDENTED, previous);
|
||||
}
|
||||
else if (ctx instanceof RenderContext) {
|
||||
ParamType paramType = ctx.paramType();
|
||||
|
||||
if (isInline(ctx))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user