[#1218] Add code generation options to generate <customTypes/> referencing a Java type and a Converter - First implementation draft

This commit is contained in:
Lukas Eder 2012-03-04 19:07:19 +00:00
parent a47284df8d
commit 54633e826d
35 changed files with 667 additions and 64 deletions

View File

@ -2742,6 +2742,11 @@ public class DefaultGenerator implements Generator {
type = strategy.getFullJavaClassName(db.getUDT(schema, u), Mode.RECORD);
}
// Check for custom types
else if (db.getConfiguredCustomType(u) != null) {
type = u;
}
// Try finding a basic standard SQL type according to the current dialect
else {
try {
@ -2818,6 +2823,12 @@ public class DefaultGenerator implements Generator {
sb.append(SQLDataType.class.getCanonicalName());
sb.append(".");
sb.append(FieldTypeHelper.normalise(sqlDataType.getTypeName()));
if (db.getConfiguredCustomType(u) != null) {
sb.append(".asConvertedDataType(new ");
sb.append(db.getConfiguredCustomType(u).getConverter());
sb.append("())");
}
}
// Otherwise, reference the dialect-specific DataType itself.

View File

@ -243,6 +243,11 @@ public class GenerationTool {
log.info("Use GenerationTool to migrate your .properties file to XML (printed on System.out) :");
log.info("Usage : GenerationTool <configuration-file> migrate");
log.info("");
log.info("XML output:");
log.info("");
JAXB.marshal(configuration, System.out);
log.info("");
log.info("");
main(configuration);
}
@ -319,6 +324,7 @@ public class GenerationTool {
database.setIncludes(defaultString(g.getDatabase().getIncludes()).split(","));
database.setExcludes(defaultString(g.getDatabase().getExcludes()).split(","));
database.setConfiguredMasterDataTables(g.getDatabase().getMasterDataTables());
database.setConfiguredCustomTypes(g.getDatabase().getCustomTypes());
database.setConfiguredEnumTypes(g.getDatabase().getEnumTypes());
database.setConfiguredForcedTypes(g.getDatabase().getForcedTypes());

View File

@ -46,6 +46,7 @@ import java.util.List;
import org.jooq.SQLDialect;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.csv.CSVReader;
import org.jooq.util.jaxb.CustomType;
import org.jooq.util.jaxb.EnumType;
import org.jooq.util.jaxb.ForcedType;
import org.jooq.util.jaxb.MasterDataTable;
@ -71,6 +72,7 @@ public abstract class AbstractDatabase implements Database {
private boolean dateAsTimestamp;
private List<Schema> configuredSchemata;
private List<MasterDataTable> configuredMasterDataTables;
private List<CustomType> configuredCustomTypes;
private List<EnumType> configuredEnumTypes;
private List<ForcedType> configuredForcedTypes;
@ -198,6 +200,27 @@ public abstract class AbstractDatabase implements Database {
return configuredEnumTypes;
}
@Override
public final void setConfiguredCustomTypes(List<CustomType> configuredCustomTypes) {
this.configuredCustomTypes = configuredCustomTypes;
}
@Override
public final List<CustomType> getConfiguredCustomTypes() {
return configuredCustomTypes;
}
@Override
public final CustomType getConfiguredCustomType(String name) {
for (CustomType type : configuredCustomTypes) {
if (type.getName().equals(name)) {
return type;
}
}
return null;
}
@Override
public final void setConfiguredForcedTypes(List<ForcedType> configuredForcedTypes) {
this.configuredForcedTypes = configuredForcedTypes;

View File

@ -37,6 +37,7 @@ package org.jooq.util;
import static org.jooq.impl.FieldTypeHelper.getDialectDataType;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
@ -130,7 +131,7 @@ abstract class AbstractTypedElementDefinition<T extends Definition>
} catch (SQLDialectNotSupportedException ignore) {}
if (dataType != null) {
if (dataType.getSQLDataType() == SQLDataType.DATE) {
if (dataType.getSQLType() == Types.DATE) {
DataType<?> forcedDataType = getDialectDataType(db.getDialect(), SQLDataType.TIMESTAMP.getTypeName(), 0, 0);
type = new DefaultDataTypeDefinition(db, getSchema(), forcedDataType.getTypeName(), 0, 0);
}

View File

@ -41,6 +41,7 @@ import java.util.List;
import org.jooq.SQLDialect;
import org.jooq.impl.Factory;
import org.jooq.util.jaxb.CustomType;
import org.jooq.util.jaxb.EnumType;
import org.jooq.util.jaxb.ForcedType;
import org.jooq.util.jaxb.MasterDataTable;
@ -186,6 +187,23 @@ public interface Database {
*/
List<MasterDataTable> getConfiguredMasterDataTables();
/**
* Database objects matching any of these field names will be generated as
* custom types
*/
void setConfiguredCustomTypes(List<CustomType> types);
/**
* Database objects matching any of these field names will be generated as
* custom types
*/
List<CustomType> getConfiguredCustomTypes();
/**
* Get a specific configured custom type by its name
*/
CustomType getConfiguredCustomType(String name);
/**
* Database objects matching any of these field names will be generated as
* enum types

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -0,0 +1,106 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//
package org.jooq.util.jaxb;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for CustomType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="CustomType">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;all>
* &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="converter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/all>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomType", propOrder = {
})
public class CustomType {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String converter;
/**
* Gets the value of the name property.
*
* @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;
}
/**
* Gets the value of the converter property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getConverter() {
return converter;
}
/**
* Sets the value of the converter property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setConverter(String value) {
this.converter = value;
}
public CustomType withName(String value) {
setName(value);
return this;
}
public CustomType withConverter(String value) {
setConverter(value);
return this;
}
}

View File

@ -0,0 +1,91 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//
package org.jooq.util.jaxb;
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.XmlType;
/**
* <p>Java class for CustomTypes complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="CustomTypes">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="customType" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}CustomType" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomTypes", propOrder = {
"customType"
})
public class CustomTypes {
protected List<CustomType> customType;
/**
* Gets the value of the customType property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the customType property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getCustomType().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link CustomType }
*
*
*/
public List<CustomType> getCustomType() {
if (customType == null) {
customType = new ArrayList<CustomType>();
}
return this.customType;
}
public CustomTypes withCustomType(CustomType... values) {
if (values!= null) {
for (CustomType value: values) {
getCustomType().add(value);
}
}
return this;
}
public CustomTypes withCustomType(Collection<CustomType> values) {
if (values!= null) {
getCustomType().addAll(values);
}
return this;
}
}

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//
@ -37,6 +37,7 @@ import javax.xml.bind.annotation.XmlType;
* &lt;element name="outputSchema" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* &lt;element name="schemata" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}Schemata" minOccurs="0"/>
* &lt;element name="masterDataTables" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}MasterDataTables" minOccurs="0"/>
* &lt;element name="customTypes" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}CustomTypes" minOccurs="0"/>
* &lt;element name="enumTypes" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}EnumTypes" minOccurs="0"/>
* &lt;element name="forcedTypes" type="{http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd}ForcedTypes" minOccurs="0"/>
* &lt;/all>
@ -73,6 +74,9 @@ public class Database {
@XmlElementWrapper(name = "masterDataTables")
@XmlElement(name = "masterDataTable")
protected List<MasterDataTable> masterDataTables;
@XmlElementWrapper(name = "customTypes")
@XmlElement(name = "customType")
protected List<CustomType> customTypes;
@XmlElementWrapper(name = "enumTypes")
@XmlElement(name = "enumType")
protected List<EnumType> enumTypes;
@ -262,6 +266,13 @@ public class Database {
return masterDataTables;
}
public List<CustomType> getCustomTypes() {
if (customTypes == null) {
customTypes = new ArrayList<CustomType>();
}
return customTypes;
}
public List<EnumType> getEnumTypes() {
if (enumTypes == null) {
enumTypes = new ArrayList<EnumType>();
@ -343,6 +354,22 @@ public class Database {
return this;
}
public Database withCustomTypes(CustomType... values) {
if (values!= null) {
for (CustomType value: values) {
getCustomTypes().add(value);
}
}
return this;
}
public Database withCustomTypes(Collection<CustomType> values) {
if (values!= null) {
getCustomTypes().addAll(values);
}
return this;
}
public Database withEnumTypes(EnumType... values) {
if (values!= null) {
for (EnumType value: values) {

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//

View File

@ -2,7 +2,7 @@
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.02 at 04:30:18 PM MEZ
// Generated on: 2012.03.04 at 05:58:26 PM MEZ
//
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

View File

@ -161,6 +161,13 @@
-->
<element name="masterDataTables" type="tns:MasterDataTables" minOccurs="0" maxOccurs="1"/>
<!--
A configuration element to configure custom types introduced to jOOQ
using converters
This is EXPERIMENTAL functionality. Use at your own risk
-->
<element name="customTypes" type="tns:CustomTypes" minOccurs="0" maxOccurs="1"/>
<!--
A configuration element to configure synthetic enum types
This is EXPERIMENTAL functionality. Use at your own risk
@ -203,6 +210,13 @@
</sequence>
</complexType>
<complexType name="CustomTypes">
<sequence>
<!-- A configuration element for a custom type -->
<element name="customType" type="tns:CustomType" minOccurs="0" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="EnumTypes">
<sequence>
<!-- A configuration element for a synthetic enum type -->
@ -230,6 +244,16 @@
</all>
</complexType>
<complexType name="CustomType">
<all>
<!-- The name of the custom type -->
<element name="name" type="string" minOccurs="1" maxOccurs="1" />
<!-- A converter implementation for the custom type -->
<element name="converter" type="string" minOccurs="1" maxOccurs="1" />
</all>
</complexType>
<complexType name="EnumType">
<all>
<!-- The name of the synthetic enum type -->

View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd">
<jdbc>
<driver>org.hsqldb.jdbcDriver</driver>
<url>jdbc:hsqldb:hsql://localhost</url>
<schema>PUBLIC</schema>
<user>sa</user>
<password></password>
</jdbc>
<generator>
<name>org.jooq.util.DefaultGenerator</name>
<database>
<name>org.jooq.util.hsqldb.HSQLDBDatabase</name>
<includes>.*</includes>
<excludes>T_BOOK_DETAILS,S_TRIGGERS_SEQUENCE</excludes>
<dateAsTimestamp>false</dateAsTimestamp>
<unsignedTypes>true</unsignedTypes>
<masterDataTables>
<masterDataTable>
<name>T_LANGUAGE</name>
<literal>CD</literal>
<description>DESCRIPTION</description>
</masterDataTable>
<masterDataTable>
<name>T_658_11</name>
</masterDataTable>
<masterDataTable>
<name>T_658_21</name>
</masterDataTable>
<masterDataTable>
<name>T_658_31</name>
</masterDataTable>
<masterDataTable>
<name>T_658_12</name>
<literal>CD</literal>
</masterDataTable>
<masterDataTable>
<name>T_658_22</name>
<literal>CD</literal>
</masterDataTable>
<masterDataTable>
<name>T_658_32</name>
<literal>CD</literal>
</masterDataTable>
</masterDataTables>
<customTypes>
<customType>
<name>org.jooq.test._.StringEnum</name>
<converter>org.jooq.test._.StringEnumMapper</converter>
</customType>
<customType>
<name>org.jooq.test._.OrdinalEnum</name>
<converter>org.jooq.test._.OrdinalEnumMapper</converter>
</customType>
</customTypes>
<enumTypes>
<enumType>
<name>BOOLEAN_YN_LC</name>
<literals>y,&quot;n&quot;</literals>
</enumType>
<enumType>
<name>BOOLEAN_YN_UC</name>
<literals>&quot;Y&quot;,N</literals>
</enumType>
<enumType>
<name>BOOLEAN_TRUE_FALSE_LC</name>
<literals>true,false</literals>
</enumType>
<enumType>
<name>BOOLEAN_TRUE_FALSE_UC</name>
<literals>TRUE,FALSE</literals>
</enumType>
<enumType>
<name>BOOLEAN_10</name>
<literals>1,0</literals>
</enumType>
<enumType>
<name>BOOLEAN_YES_NO_LC</name>
<literals>yes,no</literals>
</enumType>
<enumType>
<name>BOOLEAN_YES_NO_UC</name>
<literals>&quot;YES&quot;,&quot;NO&quot;</literals>
</enumType>
</enumTypes>
<forcedTypes>
<forcedType>
<name>org.jooq.test._.StringEnum</name>
<expressions>(?i:(.*?\.)?T_MAPPED_TYPES.DEFAULT_ENUM_NAME)</expressions>
</forcedType>
<forcedType>
<name>org.jooq.test._.OrdinalEnum</name>
<expressions>(?i:(.*?\.)?T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_YES_NO_LC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.YES_NO_LC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_YES_NO_UC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.YES_NO_UC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.(VC|C|N)_BOOLEAN)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_YN_LC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.Y_N_LC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_YN_UC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.Y_N_UC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_TRUE_FALSE_LC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.TRUE_FALSE_LC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_TRUE_FALSE_UC</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.TRUE_FALSE_UC)</expressions>
</forcedType>
<forcedType>
<name>BOOLEAN_10</name>
<expressions>(?i:(.*?.)?T_BOOLEANS.ONE_ZERO)</expressions>
</forcedType>
</forcedTypes>
</database>
<generate>
<relations>true</relations>
<navigationMethods>true</navigationMethods>
<deprecated>true</deprecated>
<instanceFields>true</instanceFields>
<generatedAnnotation>true</generatedAnnotation>
<records>true</records>
<pojos>false</pojos>
<jpaAnnotations>false</jpaAnnotations>
</generate>
<target>
<packageName>org.jooq.test.hsqldb.generatedclasses</packageName>
<directory>./src</directory>
</target>
</generator>
</configuration>

View File

@ -27,7 +27,7 @@
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.classpathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.jooq.util.GenerationTool"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="/org/jooq/configuration/${env_var:USERNAME}/hsqldb/library.properties"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="/org/jooq/configuration/${env_var:USERNAME}/hsqldb/library.xml"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jOOQ-codegen"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.maven.ide.eclipse.launchconfig.sourcepathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:jOOQ-test}"/>

View File

@ -0,0 +1,41 @@
/**
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.test._;
public enum OrdinalEnum {
A, B, C
}

View File

@ -38,19 +38,19 @@ package org.jooq.test._;
import org.jooq.Converter;
public class MyEnumNumericMapper implements Converter<Integer, MyEnum> {
public class OrdinalEnumMapper implements Converter<Integer, OrdinalEnum> {
/**
* Generated UID
*/
private static final long serialVersionUID = -4252074829213730476L;
public static final MyEnumNumericMapper INSTANCE = new MyEnumNumericMapper();
public static final OrdinalEnumMapper INSTANCE = new OrdinalEnumMapper();
@Override
public MyEnum from(Integer t) {
public OrdinalEnum from(Integer t) {
try {
return MyEnum.values()[t];
return OrdinalEnum.values()[t];
}
catch (Exception e) {
return null;
@ -58,7 +58,7 @@ public class MyEnumNumericMapper implements Converter<Integer, MyEnum> {
}
@Override
public Integer to(MyEnum u) {
public Integer to(OrdinalEnum u) {
return u == null ? null : u.ordinal();
}
@ -68,7 +68,7 @@ public class MyEnumNumericMapper implements Converter<Integer, MyEnum> {
}
@Override
public Class<MyEnum> toType() {
return MyEnum.class;
public Class<OrdinalEnum> toType() {
return OrdinalEnum.class;
}
}

View File

@ -35,7 +35,7 @@
*/
package org.jooq.test._;
public enum MyEnum {
public enum StringEnum {
A, B, C
}

View File

@ -37,19 +37,19 @@ package org.jooq.test._;
import org.jooq.Converter;
public class MyEnumStringMapper implements Converter<String, MyEnum> {
public class StringEnumMapper implements Converter<String, StringEnum> {
/**
* Generated UID
*/
private static final long serialVersionUID = -4252074829213730476L;
private static final long serialVersionUID = -4252074829213730476L;
public static final MyEnumStringMapper INSTANCE = new MyEnumStringMapper();
public static final StringEnumMapper INSTANCE = new StringEnumMapper();
@Override
public MyEnum from(String t) {
public StringEnum from(String t) {
try {
return MyEnum.valueOf(t);
return StringEnum.valueOf(t);
}
catch (Exception e) {
return null;
@ -57,7 +57,7 @@ public class MyEnumStringMapper implements Converter<String, MyEnum> {
}
@Override
public String to(MyEnum u) {
public String to(StringEnum u) {
return u == null ? null : u.name();
}
@ -67,7 +67,7 @@ public class MyEnumStringMapper implements Converter<String, MyEnum> {
}
@Override
public Class<MyEnum> toType() {
return MyEnum.class;
public Class<StringEnum> toType() {
return StringEnum.class;
}
}

View File

@ -10,7 +10,7 @@ package org.jooq.test.hsqldb.generatedclasses.tables;
comments = "This class is generated by jOOQ")
public class TMappedTypes extends org.jooq.impl.UpdatableTableImpl<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> {
private static final long serialVersionUID = -597946068;
private static final long serialVersionUID = 1206625875;
/**
* The singleton instance of PUBLIC.T_MAPPED_TYPES
@ -50,12 +50,12 @@ public class TMappedTypes extends org.jooq.impl.UpdatableTableImpl<org.jooq.test
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.lang.Integer> DEFAULT_ENUM_ORDINAL = createField("DEFAULT_ENUM_ORDINAL", org.jooq.impl.SQLDataType.INTEGER, this);
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, org.jooq.test._.OrdinalEnum> DEFAULT_ENUM_ORDINAL = createField("DEFAULT_ENUM_ORDINAL", org.jooq.impl.SQLDataType.INTEGER.asConvertedDataType(new org.jooq.test._.OrdinalEnumMapper()), this);
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.lang.String> DEFAULT_ENUM_NAME = createField("DEFAULT_ENUM_NAME", org.jooq.impl.SQLDataType.VARCHAR, this);
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, org.jooq.test._.StringEnum> DEFAULT_ENUM_NAME = createField("DEFAULT_ENUM_NAME", org.jooq.impl.SQLDataType.VARCHAR.asConvertedDataType(new org.jooq.test._.StringEnumMapper()), this);
/**
* An uncommented item

View File

@ -10,7 +10,7 @@ package org.jooq.test.hsqldb.generatedclasses.tables.records;
comments = "This class is generated by jOOQ")
public class TMappedTypesRecord extends org.jooq.impl.UpdatableRecordImpl<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> {
private static final long serialVersionUID = 1736776678;
private static final long serialVersionUID = 242486662;
/**
* An uncommented item
@ -61,28 +61,28 @@ public class TMappedTypesRecord extends org.jooq.impl.UpdatableRecordImpl<org.jo
/**
* An uncommented item
*/
public void setDefaultEnumOrdinal(java.lang.Integer value) {
public void setDefaultEnumOrdinal(org.jooq.test._.OrdinalEnum value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL, value);
}
/**
* An uncommented item
*/
public java.lang.Integer getDefaultEnumOrdinal() {
public org.jooq.test._.OrdinalEnum getDefaultEnumOrdinal() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL);
}
/**
* An uncommented item
*/
public void setDefaultEnumName(java.lang.String value) {
public void setDefaultEnumName(org.jooq.test._.StringEnum value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_NAME, value);
}
/**
* An uncommented item
*/
public java.lang.String getDefaultEnumName() {
public org.jooq.test._.StringEnum getDefaultEnumName() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_NAME);
}

View File

@ -70,9 +70,8 @@ import org.jooq.UDTRecord;
import org.jooq.UpdatableTable;
import org.jooq.conf.Settings;
import org.jooq.impl.Factory;
import org.jooq.test._.MyEnum;
import org.jooq.test._.MyEnumNumericMapper;
import org.jooq.test._.MyEnumStringMapper;
import org.jooq.test._.OrdinalEnum;
import org.jooq.test._.StringEnum;
import org.jooq.test.hsqldb.generatedclasses.PublicFactory;
import org.jooq.test.hsqldb.generatedclasses.Routines;
import org.jooq.test.hsqldb.generatedclasses.Sequences;
@ -686,8 +685,8 @@ public class jOOQHSQLDBTest extends jOOQAbstractTest<
// Storing a record using fields from a mapper
record = create().newRecord(T_MAPPED_TYPES);
record.setId(1);
record.setValue(T_MAPPED_TYPES.DEFAULT_ENUM_NAME, MyEnum.A, MyEnumStringMapper.INSTANCE);
record.setValue(T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL, MyEnum.B, MyEnumNumericMapper.INSTANCE);
record.setValue(T_MAPPED_TYPES.DEFAULT_ENUM_NAME, StringEnum.A);
record.setValue(T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL, OrdinalEnum.B);
assertEquals(1, record.store());
@ -695,7 +694,7 @@ public class jOOQHSQLDBTest extends jOOQAbstractTest<
record = create().newRecord(T_MAPPED_TYPES);
record.setId(1);
record.refresh();
assertEquals(MyEnum.A, record.getValue(T_MAPPED_TYPES.DEFAULT_ENUM_NAME, MyEnumStringMapper.INSTANCE));
assertEquals(MyEnum.B, record.getValue(T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL, MyEnumNumericMapper.INSTANCE));
assertEquals(StringEnum.A, record.getValue(T_MAPPED_TYPES.DEFAULT_ENUM_NAME));
assertEquals(OrdinalEnum.B, record.getValue(T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL));
}
}

View File

@ -99,6 +99,11 @@ public interface DataType<T> extends Serializable {
*/
<E extends EnumType> DataType<E> asEnumDataType(Class<E> enumDataType);
/**
* Retrieve the data type for a given converter
*/
<U> DataType<U> asConvertedDataType(Converter<? super T, U> converter);
/**
* Retrieve the dialect-specific type name associated with this data type
*/

View File

@ -49,6 +49,7 @@ import java.util.Map;
import org.jooq.ArrayRecord;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.EnumType;
import org.jooq.MasterDataType;
@ -192,7 +193,7 @@ public abstract class AbstractDataType<T> implements DataType<T> {
}
@Override
public final int getSQLType() {
public /* final */ int getSQLType() {
if (type == Blob.class) {
return Types.BLOB;
}
@ -310,7 +311,7 @@ public abstract class AbstractDataType<T> implements DataType<T> {
}
@Override
public final String getCastTypeName(Configuration configuration, int precision, int scale) {
public /* final */ String getCastTypeName(Configuration configuration, int precision, int scale) {
String result = getCastTypeName(configuration);
if (precision != 0) {
@ -354,13 +355,18 @@ public abstract class AbstractDataType<T> implements DataType<T> {
return new DefaultDataType<E>(dialect, enumDataType, typeName, castTypeName);
}
@Override
public final <U> DataType<U> asConvertedDataType(Converter<? super T, U> converter) {
return new ConvertedDataType<T, U>(this, converter);
}
@Override
public final SQLDialect getDialect() {
return dialect;
}
@Override
public final T convert(Object object) {
public /* final */ T convert(Object object) {
return Convert.convert(object, type);
}

View File

@ -0,0 +1,93 @@
/**
* Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.impl;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.DataType;
/**
* A <code>DataType</code> used for converted types using {@link Converter}
*
* @author Lukas Eder
*/
class ConvertedDataType<T, U> extends AbstractDataType<U> {
/**
* Generated UID
*/
private static final long serialVersionUID = -2321926692580974126L;
private final DataType<T> delegate;
private final Converter<? super T, U> converter;
ConvertedDataType(DataType<T> delegate, Converter<? super T, U> converter) {
super(null, null,
converter.toType(),
delegate.getTypeName(),
delegate.getCastTypeName());
this.delegate = delegate;
this.converter = converter;
DataTypes.registerConverter(converter.toType(), converter);
}
@Override
public int getSQLType() {
return delegate.getSQLType();
}
@Override
public String getTypeName(Configuration configuration) {
return delegate.getTypeName(configuration);
}
@Override
public String getCastTypeName(Configuration configuration) {
return delegate.getCastTypeName(configuration);
}
@Override
public String getCastTypeName(Configuration configuration, int precision, int scale) {
return delegate.getCastTypeName(configuration, precision, scale);
}
@Override
public U convert(Object object) {
return converter.from(delegate.convert(converter.to((U) object)));
}
}

View File

@ -40,9 +40,6 @@ import java.util.Map;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.exception.DataTypeException;
/**
@ -52,7 +49,6 @@ import org.jooq.exception.DataTypeException;
*/
public final class DataTypes {
private static final Object INIT_LOCK = new Object();
private static final Map<Class<?>, Converter<?, ?>> CONVERTERS = new HashMap<Class<?>, Converter<?, ?>>();
// ------------------------------------------------------------------------
@ -105,17 +101,6 @@ public final class DataTypes {
}
}
/**
* Register a <code>Converter</code> for a field
* <p>
* This registers a converter for a specific field in your generated schema.
* This converter will be used by jOOQ to convert database types to your own
* custom types and deliver those types in {@link Record} and {@link Result}
*/
public static final synchronized <T> void registerConverter(Field<T> field, Converter<T, ?> converter) {
}
// ------------------------------------------------------------------------
// XXX: Internal API
// ------------------------------------------------------------------------

View File

@ -54,6 +54,7 @@ import java.util.Arrays;
import org.jooq.ArrayRecord;
import org.jooq.BindContext;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.EnumType;
import org.jooq.MasterDataType;
import org.jooq.SQLDialect;
@ -97,6 +98,13 @@ class DefaultBindContext extends AbstractBindContext {
protected final BindContext bindValue0(Object value, Class<?> type) throws SQLException {
SQLDialect dialect = configuration.getDialect();
// [#650] Check first, if we have a converter for the supplied type
Converter<?, ?> converter = DataTypes.converter(type);
if (converter != null) {
value = ((Converter) converter).to(value);
type = converter.fromType();
}
if (log.isTraceEnabled()) {
if (value != null && value.getClass().isArray() && value.getClass() != byte[].class) {
log.trace("Binding variable " + peekIndex(), Arrays.asList((Object[]) value) + " (" + type + ")");

View File

@ -60,6 +60,7 @@ import java.util.Map;
import org.jooq.ArrayRecord;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.EnumType;
import org.jooq.ExecuteContext;
@ -284,7 +285,20 @@ public final class FieldTypeHelper {
throws SQLException {
Class<? extends T> type = field.getType();
return getFromResultSet(ctx, type, index);
Class<?> actual = type;
Converter<?, ? extends T> converter = DataTypes.converter(type);
if (converter != null) {
actual = converter.fromType();
}
Object result = getFromResultSet(ctx, actual, index);
if (converter != null) {
result = ((Converter) converter).from(result);
}
return (T) result;
}
@SuppressWarnings("unchecked")