From 4ec6da5e453deb6353396126f4e513f8b172bbd4 Mon Sep 17 00:00:00 2001 From: Tuomas Kiviaho Date: Tue, 8 Apr 2014 18:02:58 +0300 Subject: [PATCH] added support for ORDINAL_POSITION metadata --- .../maven/AbstractMetaDataExportMojo.java | 16 +++++++++++ .../query/sql/ant/AntMetaDataExporter.java | 12 +++++++- .../query/sql/codegen/MetaDataExporter.java | 11 +++++++- .../query/sql/codegen/MetaDataSerializer.java | 15 ++++++++-- .../codegen/OrdinalPositionComparator.java | 28 +++++++++++++++++++ .../query/sql/codegen/SQLCodegenModule.java | 3 ++ .../sql/codegen/MetaDataExporterTest.java | 14 ++++++---- .../com/mysema/query/sql/ColumnMetadata.java | 23 +++++++++++---- .../mysema/query/sql/RelationalPathBase.java | 12 ++++---- 9 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/OrdinalPositionComparator.java diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java index 940082c7a..f1a3c5ee6 100644 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java +++ b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java @@ -17,6 +17,7 @@ import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Comparator; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -248,6 +249,13 @@ public class AbstractMetaDataExportMojo extends AbstractMojo{ */ private boolean exportForeignKeys; + /** + * override default column order (default: alphabetical) + * + * @parameter + */ + private String columnComparatorClass; + /** * java import added to generated query classes: * com.bar for package (without .* notation) @@ -370,6 +378,14 @@ public class AbstractMetaDataExportMojo extends AbstractMojo{ configuration.registerNumeric(mapping.size, mapping.digits, Class.forName(mapping.javaType)); } } + if (columnComparatorClass != null) { + try { + exporter.setColumnComparatorClass( (Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class)); + } catch (ClassNotFoundException e) { + getLog().error(e); + throw new MojoExecutionException(e.getMessage(), e); + } + } exporter.setConfiguration(configuration); diff --git a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/ant/AntMetaDataExporter.java b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/ant/AntMetaDataExporter.java index 07ec52d9e..570e862fe 100644 --- a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/ant/AntMetaDataExporter.java +++ b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/ant/AntMetaDataExporter.java @@ -17,6 +17,7 @@ import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Comparator; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; @@ -182,6 +183,11 @@ public class AntMetaDataExporter extends Task { * */ private boolean beanPrintSupertype; + + /** + * override default column order (default: alphabetical) + */ + private String columnComparatorClass; /** * java import added to generated query classes: @@ -192,7 +198,8 @@ public class AntMetaDataExporter extends Task { private String[] imports; - @Override + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) public void execute() { Connection dbConn = null; File targetPackagePath = new File(targetSourceFolder); @@ -256,6 +263,9 @@ public class AntMetaDataExporter extends Task { if (sourceEncoding != null) { exporter.setSourceEncoding(sourceEncoding); } + if (columnComparatorClass != null) { + exporter.setColumnComparatorClass((Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class)); + } exporter.export(dbConn.getMetaData()); diff --git a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataExporter.java b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataExporter.java index ab2e9af1b..12f6a810e 100644 --- a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataExporter.java +++ b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataExporter.java @@ -23,6 +23,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -251,6 +252,7 @@ public class MetaDataExporter { int columnType = columns.getInt("DATA_TYPE"); Number columnSize = (Number) columns.getObject("COLUMN_SIZE"); Number columnDigits = (Number) columns.getObject("DECIMAL_DIGITS"); + int columnIndex = columns.getInt("ORDINAL_POSITION"); int nullable = columns.getInt("NULLABLE"); String propertyName = namingStrategy.getPropertyName(normalizedColumnName, classModel); @@ -269,7 +271,7 @@ public class MetaDataExporter { } Type typeModel = new ClassType(fieldType, clazz); Property property = createProperty(classModel, normalizedColumnName, propertyName, typeModel); - ColumnMetadata column = ColumnMetadata.named(normalizedColumnName).ofType(columnType); + ColumnMetadata column = ColumnMetadata.named(normalizedColumnName).ofType(columnType).withIndex(columnIndex); if (nullable == DatabaseMetaData.columnNoNulls) { column = column.notNull(); } @@ -539,6 +541,13 @@ public class MetaDataExporter { module.bind(SQLCodegenModule.INNER_CLASSES_FOR_KEYS, innerClassesForKeys); } + /** + * @param columnComparator + */ + public void setColumnComparatorClass(Class> columnComparatorClass) { + module.bind(SQLCodegenModule.COLUMN_COMPARATOR, columnComparatorClass); + } + /** * @param serializerClass */ diff --git a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataSerializer.java b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataSerializer.java index 53884d75c..c31db6835 100644 --- a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataSerializer.java +++ b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/MetaDataSerializer.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -28,6 +29,7 @@ import java.util.Set; import javax.inject.Inject; import javax.inject.Named; +import com.google.common.collect.Lists; import com.mysema.codegen.CodeWriter; import com.mysema.codegen.model.ClassType; import com.mysema.codegen.model.Parameter; @@ -63,6 +65,8 @@ public class MetaDataSerializer extends EntitySerializer { private final boolean innerClassesForKeys; private final Set imports; + + private final Comparator columnComparator; /** * Create a new MetaDataSerializer instance @@ -76,11 +80,13 @@ public class MetaDataSerializer extends EntitySerializer { TypeMappings typeMappings, NamingStrategy namingStrategy, @Named(SQLCodegenModule.INNER_CLASSES_FOR_KEYS) boolean innerClassesForKeys, - @Named(SQLCodegenModule.IMPORTS) Set imports) { + @Named(SQLCodegenModule.IMPORTS) Set imports, + @Named(SQLCodegenModule.COLUMN_COMPARATOR) Comparator columnComparator) { super(typeMappings,Collections.emptyList()); this.namingStrategy = namingStrategy; this.innerClassesForKeys = innerClassesForKeys; this.imports = new HashSet(imports); + this.columnComparator = columnComparator; } @Override @@ -202,12 +208,17 @@ public class MetaDataSerializer extends EntitySerializer { @Override protected void outro(EntityType model, CodeWriter writer) throws IOException { writer.beginPublicMethod(Types.VOID,"addMetadata"); - for (Property property : model.getProperties()) { + List properties = Lists.newArrayList(model.getProperties()); + if (columnComparator != null) { + Collections.sort(properties, columnComparator); + } + for (Property property : properties) { String name = property.getEscapedName(); ColumnMetadata metadata = (ColumnMetadata) property.getData().get("COLUMN"); StringBuilder columnMeta = new StringBuilder(); columnMeta.append("ColumnMetadata"); columnMeta.append(".named(\"" + metadata.getName() + "\")"); + columnMeta.append(".withIndex(" + metadata.getIndex() + ")"); columnMeta.append(".ofType(" + metadata.getJdbcType() + ")"); if (metadata.hasSize()) { columnMeta.append(".withSize(" + metadata.getSize() + ")"); diff --git a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/OrdinalPositionComparator.java b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/OrdinalPositionComparator.java new file mode 100644 index 000000000..5bc9079bb --- /dev/null +++ b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/OrdinalPositionComparator.java @@ -0,0 +1,28 @@ +package com.mysema.query.sql.codegen; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Map; + +import com.mysema.query.codegen.Property; +import com.mysema.query.sql.ColumnMetadata; + +public class OrdinalPositionComparator implements Comparator { + + public OrdinalPositionComparator() { + super(); + } + + @Override + public int compare(Property property1, Property property2) { + Integer comparison = null; + for (Property property : Arrays.asList(property1, property2)) { + Map data = property.getData(); + ColumnMetadata columnMetadata = (ColumnMetadata) data.get("COLUMN"); + int index = columnMetadata.getIndex(); + comparison = comparison == null ? index : comparison - index; + } + return comparison; + } + +} diff --git a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/SQLCodegenModule.java b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/SQLCodegenModule.java index cf3c2f2e0..7574e6bc4 100644 --- a/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/SQLCodegenModule.java +++ b/querydsl-sql-codegen/src/main/java/com/mysema/query/sql/codegen/SQLCodegenModule.java @@ -42,6 +42,8 @@ public class SQLCodegenModule extends CodegenModule{ public static final String SCHEMA_TO_PACKAGE = "schemaToPackage"; + public static final String COLUMN_COMPARATOR = "columnComparator"; + @Override protected void configure() { super.configure(); @@ -57,6 +59,7 @@ public class SQLCodegenModule extends CodegenModule{ bind(PACKAGE_NAME, "com.example"); bind(BEAN_SERIALIZER, (Class)null); bind(SCHEMA_TO_PACKAGE, false); + bind(COLUMN_COMPARATOR, null); } public String getPrefix() { diff --git a/querydsl-sql-codegen/src/test/java/com/mysema/query/sql/codegen/MetaDataExporterTest.java b/querydsl-sql-codegen/src/test/java/com/mysema/query/sql/codegen/MetaDataExporterTest.java index 0114e0b1d..4d8212675 100644 --- a/querydsl-sql-codegen/src/test/java/com/mysema/query/sql/codegen/MetaDataExporterTest.java +++ b/querydsl-sql-codegen/src/test/java/com/mysema/query/sql/codegen/MetaDataExporterTest.java @@ -152,14 +152,14 @@ public class MetaDataExporterTest { @Test public void NormalSettings_Repetition() throws SQLException { - test("Q", "", "", "", defaultNaming, "target/1", false, false); + test("Q", "", "", "", defaultNaming, "target/1", false, false, false); File file = new File("target/1/test/QEmployee.java"); long lastModified = file.lastModified(); assertTrue(file.exists()); clean = false; - test("Q", "", "", "", defaultNaming, "target/1", false, false); + test("Q", "", "", "", defaultNaming, "target/1", false, false, false); assertEquals(lastModified, file.lastModified()); } @@ -179,14 +179,15 @@ public class MetaDataExporterTest { for (boolean exportColumns : trueAndFalse) { for (String beanPackage : Arrays.asList("test2", null)) { for (Serializer beanSerializer : BEAN_SERIALIZERS) { + for (boolean withOriginalPositioning : trueAndFalse) { counter++; this.beanPackageName = beanPackage; this.schemaToPackage = schemaToPackage; this.exportColumns = exportColumns; this.beanSerializer = beanSerializer; test(namePrefix, nameSuffix, beanPrefix, beanSuffix, - ns, "target/multiple_"+counter, withBeans, withInnerClasses); - }}}}}}}}}}} + ns, "target/multiple_"+counter, withBeans, withInnerClasses, withOriginalPositioning); + }}}}}}}}}}}} } @Test @@ -290,7 +291,7 @@ public class MetaDataExporterTest { private void test(String namePrefix, String nameSuffix, String beanPrefix, String beanSuffix, NamingStrategy namingStrategy, String target, boolean withBeans, - boolean withInnerClasses) throws SQLException{ + boolean withInnerClasses, boolean withOrdinalPositioning) throws SQLException{ File targetDir = new File(target); if (clean) { try { @@ -318,6 +319,9 @@ public class MetaDataExporterTest { if (withBeans) { exporter.setBeanSerializer(beanSerializer); } + if (withOrdinalPositioning) { + exporter.setColumnComparatorClass(OrdinalPositionComparator.class); + } exporter.export(connection.getMetaData()); JavaCompiler compiler = new SimpleCompiler(); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java b/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java index 304ecf07c..490708f9d 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java @@ -61,12 +61,14 @@ public final class ColumnMetadata implements Serializable { * if the name is null */ public static ColumnMetadata named(String name) { - return new ColumnMetadata(name, null, true, UNDEFINED, UNDEFINED); + return new ColumnMetadata(null, name, null, true, UNDEFINED, UNDEFINED); } private static final int UNDEFINED = -1; private final String name; + + private final Integer index; private final Integer jdbcType; @@ -76,8 +78,9 @@ public final class ColumnMetadata implements Serializable { private final int decimalDigits; - private ColumnMetadata(String name, Integer jdbcType, boolean nullable, int size, + private ColumnMetadata(Integer index, String name, Integer jdbcType, boolean nullable, int size, int decimalDigits) { + this.index = index; this.name = name; this.jdbcType = jdbcType; this.nullable = nullable; @@ -88,6 +91,14 @@ public final class ColumnMetadata implements Serializable { public String getName() { return name; } + + public int getIndex() { + return index; + } + + public ColumnMetadata withIndex(int index) { + return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits); + } public int getJdbcType() { return jdbcType; @@ -98,7 +109,7 @@ public final class ColumnMetadata implements Serializable { } public ColumnMetadata ofType(int jdbcType) { - return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits); + return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits); } public boolean isNullable() { @@ -106,7 +117,7 @@ public final class ColumnMetadata implements Serializable { } public ColumnMetadata notNull() { - return new ColumnMetadata(name, jdbcType, false, size, decimalDigits); + return new ColumnMetadata(index, name, jdbcType, false, size, decimalDigits); } /** @@ -123,7 +134,7 @@ public final class ColumnMetadata implements Serializable { } public ColumnMetadata withSize(int size) { - return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits); + return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits); } /** @@ -140,7 +151,7 @@ public final class ColumnMetadata implements Serializable { } public ColumnMetadata withDigits(int decimalDigits) { - return new ColumnMetadata(name, jdbcType, nullable, size, decimalDigits); + return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits); } @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java b/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java index a53b8c0d4..a91ffb895 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java @@ -15,6 +15,7 @@ package com.mysema.query.sql; import static com.google.common.collect.ImmutableList.copyOf; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -47,9 +48,7 @@ public class RelationalPathBase extends BeanPath implements RelationalPath @Nullable private PrimaryKey primaryKey; - private final List> columns = Lists.newArrayList(); - - private final Map, ColumnMetadata> columnMetadata = Maps.newHashMap(); + private final Map, ColumnMetadata> columnMetadata = Maps.newLinkedHashMap(); private final List> foreignKeys = Lists.newArrayList(); @@ -143,20 +142,19 @@ public class RelationalPathBase extends BeanPath implements RelationalPath } public Path[] all() { - Path[] all = new Path[columns.size()]; - columns.toArray(all); + Path[] all = new Path[columnMetadata.size()]; + columnMetadata.keySet().toArray(all); return all; } @Override protected

> P add(P path) { - columns.add(path); return path; } @Override public List> getColumns() { - return columns; + return Arrays.asList(all()); } @Override