[#1215] Add org.jooq.Converter<T, U> for custom type mapping

[#1216] Overload Record, Result.getValue() and .setValue() methods to accept a Converter
This commit is contained in:
Lukas Eder 2012-03-04 15:00:17 +00:00
parent 0607c8ccc7
commit 880786ff07
23 changed files with 1502 additions and 269 deletions

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 MyEnum {
A, B, C
}

View File

@ -0,0 +1,69 @@
/**
* 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._;
import org.jooq.Converter;
public class MyEnumNumericMapper implements Converter<Integer, MyEnum> {
public static final MyEnumNumericMapper INSTANCE = new MyEnumNumericMapper();
@Override
public MyEnum from(Integer t) {
try {
return MyEnum.values()[t];
}
catch (Exception e) {
return null;
}
}
@Override
public Integer to(MyEnum u) {
return u == null ? null : u.ordinal();
}
@Override
public Class<Integer> fromType() {
return Integer.class;
}
@Override
public Class<MyEnum> toType() {
return MyEnum.class;
}
}

View File

@ -0,0 +1,68 @@
/**
* 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._;
import org.jooq.Converter;
public class MyEnumStringMapper implements Converter<String, MyEnum> {
public static final MyEnumStringMapper INSTANCE = new MyEnumStringMapper();
@Override
public MyEnum from(String t) {
try {
return MyEnum.valueOf(t);
}
catch (Exception e) {
return null;
}
}
@Override
public String to(MyEnum u) {
return u == null ? null : u.name();
}
@Override
public Class<String> fromType() {
return String.class;
}
@Override
public Class<MyEnum> toType() {
return MyEnum.class;
}
}

View File

@ -35,6 +35,7 @@
*/
package org.jooq.test._.testcases;
import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@ -54,9 +55,12 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.InsertSetMoreStep;
import org.jooq.Record;
@ -270,6 +274,98 @@ extends BaseTest<A, B, S, B2S, BS, L, X, DATE, D, T, U, I, IPK, T658, T725, T639
assertEquals(dateOfBirth, record.getValueAsTime(TAuthor_DATE_OF_BIRTH()).getTime());
}
@Test
public void testCustomConversion() {
Converter<String, StringBuilder> converter = new Converter<String, StringBuilder>() {
@Override
public StringBuilder from(String databaseObject) {
return new StringBuilder("prefix_" + databaseObject);
}
@Override
public String to(StringBuilder userObject) {
return userObject.toString().replace("prefix_", "");
}
@Override
public Class<String> fromType() {
return String.class;
}
@Override
public Class<StringBuilder> toType() {
return StringBuilder.class;
}
};
List<StringBuilder> prefixed = asList(
new StringBuilder("prefix_1984"),
new StringBuilder("prefix_Animal Farm"),
new StringBuilder("prefix_O Alquimista"),
new StringBuilder("prefix_Brida"));
// Check various Result, Record methods
Result<Record> result =
create().select(TBook_TITLE())
.from(TBook())
.orderBy(TBook_ID())
.fetch();
assertEquals(strings(prefixed), strings(result.getValues(TBook_TITLE(), converter)));
assertEquals(strings(prefixed), strings(result.getValues(TBook_TITLE().getName(), converter)));
assertEquals(strings(prefixed), strings(result.getValues(0, converter)));
for (int i = 0; i < 4; i++) {
assertEquals(strings(prefixed.subList(i, i + 1)), strings(asList(result.get(i).getValue(TBook_TITLE(), converter))));
assertEquals(strings(prefixed.subList(i, i + 1)), strings(asList(result.get(i).getValue(TBook_TITLE().getName(), converter))));
assertEquals(strings(prefixed.subList(i, i + 1)), strings(asList(result.get(i).getValue(0, converter))));
}
// Check various fetch methods
assertEquals(strings(prefixed),
strings(create().select(TBook_TITLE())
.from(TBook())
.orderBy(TBook_ID())
.fetch(TBook_TITLE(), converter)));
assertEquals(strings(prefixed),
strings(create().select(TBook_TITLE())
.from(TBook())
.orderBy(TBook_ID())
.fetch(TBook_TITLE().getName(), converter)));
assertEquals(strings(prefixed),
strings(create().select(TBook_TITLE())
.from(TBook())
.orderBy(TBook_ID())
.fetch(0, converter)));
// Check various fetchOne methods
for (int i = 0; i < 4; i++) {
assertEquals(strings(prefixed.subList(i, i + 1)),
strings(asList(create().select(TBook_TITLE())
.from(TBook())
.where(TBook_ID().equal(i + 1))
.fetchOne(TBook_TITLE(), converter))));
}
// Check various fetchArray methods
StringBuilder[] array =
create().select(TBook_TITLE())
.from(TBook())
.orderBy(TBook_ID())
.fetchArray(TBook_TITLE(), converter);
assertEquals(strings(prefixed), strings(asList(array)));
}
private List<String> strings(List<StringBuilder> prefixed) {
List<String> result = new ArrayList<String>();
for (StringBuilder sb : prefixed) {
result.add(sb.toString());
}
return result;
}
@Test
public void testCastingToDialectDataType() throws Exception {
for (DataType<?> type : getCastableDataTypes()) {

View File

@ -489,7 +489,7 @@ extends BaseTest<A, B, S, B2S, BS, L, X, DATE, D, T, U, I, IPK, T658, T725, T639
assertEquals(sequence, schema.getSequence(sequence.getName()));
}
int tables = 17;
int tables = 18;
// The additional T_DIRECTORY table for recursive queries
if (supportsRecursiveQueries()) {
@ -545,7 +545,7 @@ extends BaseTest<A, B, S, B2S, BS, L, X, DATE, D, T, U, I, IPK, T658, T725, T639
// [#610] Collision-prone entities are only available in HSQLDB
else if (getDialect() == HSQLDB) {
assertEquals(tables + 9, schema.getTables().size());
assertEquals(tables + 11, schema.getTables().size());
}
else {

View File

@ -63,6 +63,20 @@ DROP TABLE IF EXISTS prepared_statement/
DROP TABLE IF EXISTS t_booleans/
DROP TABLE IF EXISTS t_identity/
DROP TABLE IF EXISTS t_identity_pk/
DROP TABLE IF EXISTS t_mapped_types/
CREATE TABLE t_mapped_types (
id int,
java_util_date timestamp,
java_util_calendar timestamp,
default_enum_ordinal int,
default_enum_name varchar(10),
custom_enum_numeric int,
custom_enum_text varchar(10),
CONSTRAINT pk_t_mapped_types PRIMARY KEY (id)
)
/
CREATE TABLE t_identity_pk (
id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1),

View File

@ -29,6 +29,7 @@ public class Keys extends org.jooq.impl.AbstractKeys {
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TBooleansRecord> PK_T_BOOLEANS = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.TBooleans.T_BOOLEANS, org.jooq.test.hsqldb.generatedclasses.tables.TBooleans.T_BOOLEANS.ID);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TDatesRecord> PK_T_DATES = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.TDates.T_DATES, org.jooq.test.hsqldb.generatedclasses.tables.TDates.T_DATES.ID);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TIdentityPkRecord> PK_T_IDENTITY_PK = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.TIdentityPk.T_IDENTITY_PK, org.jooq.test.hsqldb.generatedclasses.tables.TIdentityPk.T_IDENTITY_PK.ID);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> PK_T_MAPPED_TYPES = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES, org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.ID);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TTriggersRecord> PK_T_TRIGGERS = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.TTriggers.T_TRIGGERS, org.jooq.test.hsqldb.generatedclasses.tables.TTriggers.T_TRIGGERS.ID_GENERATED);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.XTestCase_64_69Record> PK_X_TEST_CASE_64_69 = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.XTestCase_64_69.X_TEST_CASE_64_69, org.jooq.test.hsqldb.generatedclasses.tables.XTestCase_64_69.X_TEST_CASE_64_69.ID);
public static final org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.XTestCase_71Record> PK_X_TEST_CASE_71 = createUniqueKey(org.jooq.test.hsqldb.generatedclasses.tables.XTestCase_71.X_TEST_CASE_71, org.jooq.test.hsqldb.generatedclasses.tables.XTestCase_71.X_TEST_CASE_71.ID);

View File

@ -10,7 +10,7 @@ package org.jooq.test.hsqldb.generatedclasses;
comments = "This class is generated by jOOQ")
public class Public extends org.jooq.impl.SchemaImpl {
private static final long serialVersionUID = -459797272;
private static final long serialVersionUID = 65328174;
/**
* The singleton instance of PUBLIC
@ -55,6 +55,7 @@ public class Public extends org.jooq.impl.SchemaImpl {
org.jooq.test.hsqldb.generatedclasses.tables.TDates.T_DATES,
org.jooq.test.hsqldb.generatedclasses.tables.TIdentity.T_IDENTITY,
org.jooq.test.hsqldb.generatedclasses.tables.TIdentityPk.T_IDENTITY_PK,
org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES,
org.jooq.test.hsqldb.generatedclasses.tables.TTriggers.T_TRIGGERS,
org.jooq.test.hsqldb.generatedclasses.tables.VAuthor.V_AUTHOR,
org.jooq.test.hsqldb.generatedclasses.tables.VBook.V_BOOK,

View File

@ -127,6 +127,11 @@ public final class Tables {
*/
public static org.jooq.test.hsqldb.generatedclasses.tables.TIdentityPk T_IDENTITY_PK = org.jooq.test.hsqldb.generatedclasses.tables.TIdentityPk.T_IDENTITY_PK;
/**
* The table PUBLIC.T_MAPPED_TYPES
*/
public static org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes T_MAPPED_TYPES = org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES;
/**
* The table PUBLIC.T_TRIGGERS
*/

View File

@ -0,0 +1,99 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.hsqldb.generatedclasses.tables;
/**
* This class is generated by jOOQ.
*/
@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.6"},
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;
/**
* The singleton instance of PUBLIC.T_MAPPED_TYPES
*/
public static final org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes T_MAPPED_TYPES = new org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes();
/**
* The class holding records for this type
*/
private static final java.lang.Class<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> __RECORD_TYPE = org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord.class;
/**
* The class holding records for this type
*/
@Override
public java.lang.Class<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> getRecordType() {
return __RECORD_TYPE;
}
/**
* An uncommented item
*
* PRIMARY KEY
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.lang.Integer> ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER, this);
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.sql.Timestamp> JAVA_UTIL_DATE = createField("JAVA_UTIL_DATE", org.jooq.impl.SQLDataType.TIMESTAMP, this);
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.sql.Timestamp> JAVA_UTIL_CALENDAR = createField("JAVA_UTIL_CALENDAR", org.jooq.impl.SQLDataType.TIMESTAMP, this);
/**
* 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);
/**
* 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);
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.lang.Integer> CUSTOM_ENUM_NUMERIC = createField("CUSTOM_ENUM_NUMERIC", org.jooq.impl.SQLDataType.INTEGER, this);
/**
* An uncommented item
*/
public final org.jooq.TableField<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord, java.lang.String> CUSTOM_ENUM_TEXT = createField("CUSTOM_ENUM_TEXT", org.jooq.impl.SQLDataType.VARCHAR, this);
/**
* No further instances allowed
*/
private TMappedTypes() {
super("T_MAPPED_TYPES", org.jooq.test.hsqldb.generatedclasses.Public.PUBLIC);
}
/**
* No further instances allowed
*/
private TMappedTypes(java.lang.String alias) {
super(alias, org.jooq.test.hsqldb.generatedclasses.Public.PUBLIC, org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES);
}
@Override
public org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord> getMainKey() {
return org.jooq.test.hsqldb.generatedclasses.Keys.PK_T_MAPPED_TYPES;
}
@Override
@SuppressWarnings("unchecked")
public java.util.List<org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord>> getKeys() {
return java.util.Arrays.<org.jooq.UniqueKey<org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord>>asList(org.jooq.test.hsqldb.generatedclasses.Keys.PK_T_MAPPED_TYPES);
}
@Override
public org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes as(java.lang.String alias) {
return new org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes(alias);
}
}

View File

@ -0,0 +1,123 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.hsqldb.generatedclasses.tables.records;
/**
* This class is generated by jOOQ.
*/
@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.6"},
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;
/**
* An uncommented item
*
* PRIMARY KEY
*/
public void setId(java.lang.Integer value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.ID, value);
}
/**
* An uncommented item
*
* PRIMARY KEY
*/
public java.lang.Integer getId() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.ID);
}
/**
* An uncommented item
*/
public void setJavaUtilDate(java.sql.Timestamp value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.JAVA_UTIL_DATE, value);
}
/**
* An uncommented item
*/
public java.sql.Timestamp getJavaUtilDate() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.JAVA_UTIL_DATE);
}
/**
* An uncommented item
*/
public void setJavaUtilCalendar(java.sql.Timestamp value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.JAVA_UTIL_CALENDAR, value);
}
/**
* An uncommented item
*/
public java.sql.Timestamp getJavaUtilCalendar() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.JAVA_UTIL_CALENDAR);
}
/**
* An uncommented item
*/
public void setDefaultEnumOrdinal(java.lang.Integer value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_ORDINAL, value);
}
/**
* An uncommented item
*/
public java.lang.Integer 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) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_NAME, value);
}
/**
* An uncommented item
*/
public java.lang.String getDefaultEnumName() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.DEFAULT_ENUM_NAME);
}
/**
* An uncommented item
*/
public void setCustomEnumNumeric(java.lang.Integer value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.CUSTOM_ENUM_NUMERIC, value);
}
/**
* An uncommented item
*/
public java.lang.Integer getCustomEnumNumeric() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.CUSTOM_ENUM_NUMERIC);
}
/**
* An uncommented item
*/
public void setCustomEnumText(java.lang.String value) {
setValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.CUSTOM_ENUM_TEXT, value);
}
/**
* An uncommented item
*/
public java.lang.String getCustomEnumText() {
return getValue(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES.CUSTOM_ENUM_TEXT);
}
/**
* Create a detached TMappedTypesRecord
*/
public TMappedTypesRecord() {
super(org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES);
}
}

View File

@ -772,6 +772,11 @@ public abstract class jOOQAbstractTest<
new DataTypeTests(this).testConversionResult();
}
@Test
public void testCustomConversion() throws Exception {
new DataTypeTests(this).testCustomConversion();
}
@Test
public void testForUpdateClauses() throws Exception {
new SelectTests(this).testForUpdateClauses();

View File

@ -36,6 +36,7 @@
package org.jooq.test;
import static junit.framework.Assert.assertEquals;
import static org.jooq.test.hsqldb.generatedclasses.Tables.T_639_NUMBERS_TABLE;
import static org.jooq.test.hsqldb.generatedclasses.Tables.T_658_REF;
import static org.jooq.test.hsqldb.generatedclasses.Tables.T_725_LOB_TEST;
@ -52,6 +53,7 @@ import static org.jooq.test.hsqldb.generatedclasses.Tables.T_TRIGGERS;
import static org.jooq.test.hsqldb.generatedclasses.Tables.V_AUTHOR;
import static org.jooq.test.hsqldb.generatedclasses.Tables.V_BOOK;
import static org.jooq.test.hsqldb.generatedclasses.Tables.V_LIBRARY;
import static org.jooq.test.hsqldb.generatedclasses.tables.TMappedTypes.T_MAPPED_TYPES;
import java.math.BigDecimal;
import java.math.BigInteger;
@ -68,6 +70,9 @@ 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.hsqldb.generatedclasses.PublicFactory;
import org.jooq.test.hsqldb.generatedclasses.Routines;
import org.jooq.test.hsqldb.generatedclasses.Sequences;
@ -79,6 +84,7 @@ import org.jooq.test.hsqldb.generatedclasses.tables.records.TBookToBookStoreReco
import org.jooq.test.hsqldb.generatedclasses.tables.records.TDatesRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.TIdentityPkRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.TIdentityRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.TMappedTypesRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.TTriggersRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.T_639NumbersTableRecord;
import org.jooq.test.hsqldb.generatedclasses.tables.records.T_658RefRecord;
@ -92,6 +98,8 @@ import org.jooq.tools.unsigned.ULong;
import org.jooq.tools.unsigned.UShort;
import org.jooq.util.hsqldb.HSQLDBDataType;
import org.junit.Test;
/**
* @author Lukas Eder
*/
@ -668,4 +676,26 @@ public class jOOQHSQLDBTest extends jOOQAbstractTest<
HSQLDBDataType.VARCHARIGNORECASE,
};
}
@Test
public void testMapper() {
jOOQAbstractTest.reset = false;
TMappedTypesRecord record;
// 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);
assertEquals(1, record.store());
// Retrieving that record again using fields from a mapper
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));
}
}

View File

@ -0,0 +1,85 @@
/**
* 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;
import org.jooq.impl.SQLDataType;
/**
* A <code>Converter</code> for data types.
* <p>
* A general data type conversion interface that can be provided to jOOQ at
* various places in order to perform custom data type conversion. Conversion is
* directed, this means that the <code>Converter</code> is used
* <ul>
* <li>to load database types converting them to user types "FROM" the database.
* Hence, {@link #fromType()} is the type as defined in the database.</li>
* <li>to store user types converting them to database types "TO" the database.
* Hence, {@link #toType()} is the user-defined type</li>
* </ul>
*
* @author Lukas Eder
* @param <T> The database type - i.e. any type available from
* {@link SQLDataType}
* @param <U> The user type
*/
public interface Converter<T, U> {
/**
* Convert a database object to a user object
*
* @param databaseObject The database object
* @return The user object
*/
U from(T databaseObject);
/**
* Convert a user object to a database object
*
* @param userObject The user object
* @return The database object
*/
T to(U userObject);
/**
* The database type
*/
Class<T> fromType();
/**
* The user type
*/
Class<U> toType();
}

View File

@ -946,6 +946,41 @@ public interface Record extends FieldProvider, Store<Object> {
<T> T getValue(Field<?> field, Class<? extends T> type, T defaultValue) throws IllegalArgumentException,
DataTypeException;
/**
* Get a converted value from this Record, providing a field.
*
* @param <T> The database type parameter
* @param <U> The conversion type parameter
* @param field The field
* @param converter The data type converter
* @return The value of a field contained in this record
* @throws IllegalArgumentException If the argument field is not contained
* in {@link #getFields()}
* @throws DataTypeException wrapping any data type conversion exception
* that might have occurred
* @see Convert#convert(Object, Converter)
*/
<T, U> U getValue(Field<T> field, Converter<? super T, U> converter) throws IllegalArgumentException, DataTypeException;
/**
* Get a converted value from this record, providing a field.
*
* @param <T> The database type parameter
* @param <U> The conversion type parameter
* @param field The field
* @param converter The data type converter
* @param defaultValue The default value instead of <code>null</code>
* @return The value of a field contained in this record, or defaultValue,
* if <code>null</code>
* @throws IllegalArgumentException If the argument field is not contained
* in {@link #getFields()}
* @throws DataTypeException wrapping any data type conversion exception
* that might have occurred
* @see Convert#convert(Object, Converter)
*/
<T, U> U getValue(Field<T> field, Converter<? super T, U> converter, U defaultValue) throws IllegalArgumentException,
DataTypeException;
/**
* Get a converted value from this Record, providing a field name.
*
@ -979,6 +1014,72 @@ public interface Record extends FieldProvider, Store<Object> {
<T> T getValue(String fieldName, Class<? extends T> type, T defaultValue) throws IllegalArgumentException,
DataTypeException;
/**
* Get a converted value from this Store, providing a field index.
*
* @param <U> The conversion type parameter
* @param index The field's index
* @param converter The data type converter
* @return The value of a field's index contained in this Store
* @throws IllegalArgumentException If the argument index is not contained
* in the Store
* @throws DataTypeException wrapping data type conversion exception that
* might have occurred
* @see Convert#convert(Object, Converter)
*/
<U> U getValue(int index, Converter<?, U> converter) throws IllegalArgumentException, DataTypeException;
/**
* Get a converted value from this Store, providing a field index.
*
* @param <U> The conversion type parameter
* @param index The field's index
* @param converter The data type converter
* @param defaultValue The default value instead of <code>null</code>
* @return The value of a field's index contained in this Store, or
* defaultValue, if <code>null</code>
* @throws IllegalArgumentException If the argument index is not contained
* in the Store
* @throws DataTypeException wrapping data type conversion exception that
* might have occurred
* @see Convert#convert(Object, Converter)
*/
<U> U getValue(int index, Converter<?, U> converter, U defaultValue) throws IllegalArgumentException,
DataTypeException;
/**
* Get a converted value from this Record, providing a field name.
*
* @param <U> The conversion type parameter
* @param fieldName The field's name
* @param converter The data type converter
* @return The value of a field's name contained in this record
* @throws IllegalArgumentException If the argument fieldName is not
* contained in the record
* @throws DataTypeException wrapping any data type conversion exception
* that might have occurred
* @see Convert#convert(Object, Converter)
*/
<U> U getValue(String fieldName, Converter<?, U> converter) throws IllegalArgumentException, DataTypeException;
/**
* Get a converted value from this record, providing a field name.
*
* @param <U> The conversion type parameter
* @param fieldName The field's name
* @param converter The data type converter
* @param defaultValue The default value instead of <code>null</code>
* @return The value of a field's name contained in this record, or
* defaultValue, if <code>null</code>
* @throws IllegalArgumentException If the argument fieldName is not
* contained in the record
* @throws DataTypeException wrapping any data type conversion exception
* that might have occurred
* @see Convert#convert(Object, Converter)
*/
<U> U getValue(String fieldName, Converter<?, U> converter, U defaultValue) throws IllegalArgumentException,
DataTypeException;
/**
* Set a value into this record.
*
@ -988,6 +1089,18 @@ public interface Record extends FieldProvider, Store<Object> {
*/
<T> void setValue(Field<T> field, T value);
/**
* Set a value into this record.
*
* @param <T> The generic field parameter
* @param <U> The conversion type parameter
* @param field The field
* @param value The value
* @param converter The converter used to convert <code>value</code> into an
* appropriate type
*/
<T, U> void setValue(Field<T> field, U value, Converter<T, ? super U> converter);
/**
* Convert this record into an array.
* <p>

View File

@ -1252,6 +1252,18 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
<T> List<T> getValues(Field<?> field, Class<? extends T> type);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
*
* @param field The values' field
* @param converter The data type converter used for type conversion
* @return The values
* @see Record#getValue(Field, Converter)
* @see Convert#convert(Object, Converter)
*/
<T, U> List<U> getValues(Field<T> field, Converter<? super T, U> converter);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
@ -1273,6 +1285,18 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
<T> List<T> getValues(int fieldIndex, Class<? extends T> type);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
*
* @param fieldIndex The values' field index
* @param converter The data type converter used for type conversion
* @return The values
* @see Record#getValue(int, Converter)
* @see Convert#convert(Object, Converter)
*/
<U> List<U> getValues(int fieldIndex, Converter<?, U> converter);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
@ -1294,6 +1318,18 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
<T> List<T> getValues(String fieldName, Class<? extends T> type);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
*
* @param fieldName The values' field name
* @param converter The data type converter used for type conversion
* @return The values
* @see Record#getValue(String, Converter)
* @see Convert#convert(Object, Converter)
*/
<U> List<U> getValues(String fieldName, Converter<?, U> converter);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.

View File

@ -171,7 +171,7 @@ public interface ResultQuery<R extends Record> extends Query {
* result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(Field)}
* {@link Result#getValues(Field, Class)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
@ -179,6 +179,19 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> List<T> fetch(Field<?> field, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(Field, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(Field, Converter)
*/
<T, U> List<U> fetch(Field<T> field, Converter<? super T, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
@ -204,6 +217,19 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> List<T> fetch(int fieldIndex, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(int, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(int, Converter)
*/
<U> List<U> fetch(int fieldIndex, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
@ -229,6 +255,19 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> List<T> fetch(String fieldName, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(String, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(String, Converter)
*/
<U> List<U> fetch(String fieldName, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
@ -246,6 +285,40 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> T fetchOne(Field<T> field) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
* <p>
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Class)}
*
* @return The resulting value or <code>null</code> if the query returned no
* records.
* @throws DataAccessException This exception is thrown
* <ul>
* <li>if something went wrong executing the query</li> <li>if
* the query returned more than one value</li>
* </ul>
*/
<T> T fetchOne(Field<?> field, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
* <p>
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Converter)}
*
* @return The resulting value or <code>null</code> if the query returned no
* records.
* @throws DataAccessException This exception is thrown
* <ul>
* <li>if something went wrong executing the query</li> <li>if
* the query returned more than one value</li>
* </ul>
*/
<T, U> U fetchOne(Field<T> field, Converter<? super T, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
@ -280,6 +353,23 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> T fetchOne(int fieldIndex, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
* <p>
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int, Converter)}
*
* @return The resulting value or <code>null</code> if the query returned no
* records.
* @throws DataAccessException This exception is thrown
* <ul>
* <li>if something went wrong executing the query</li> <li>if
* the query returned more than one value</li>
* </ul>
*/
<U> U fetchOne(int fieldIndex, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
@ -314,6 +404,23 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> T fetchOne(String fieldName, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
* <p>
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(String, Converter)}
*
* @return The resulting value or <code>null</code> if the query returned no
* records.
* @throws DataAccessException This exception is thrown
* <ul>
* <li>if something went wrong executing the query</li> <li>if
* the query returned more than one value</li>
* </ul>
*/
<U> U fetchOne(String fieldName, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return at most one resulting record.
*
@ -440,6 +547,17 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> T[] fetchArray(int fieldIndex, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
* <p>
* You can access data like this
* <code><pre>query.fetchArray(fieldIndex)[recordIndex]</pre></code>
*
* @return The resulting values.
*/
<U> U[] fetchArray(int fieldIndex, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
@ -452,6 +570,18 @@ public interface ResultQuery<R extends Record> extends Query {
*/
Object[] fetchArray(String fieldName) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
* <p>
* You can access data like this
* <code><pre>query.fetchArray(fieldName)[recordIndex]</pre></code>
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
<U> U[] fetchArray(String fieldName, Converter<?, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
@ -476,6 +606,30 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<T> T[] fetchArray(Field<T> field) throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
* <p>
* You can access data like this
* <code><pre>query.fetchArray(field)[recordIndex]</pre></code>
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
<T> T[] fetchArray(Field<?> field, Class<? extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
* <p>
* You can access data like this
* <code><pre>query.fetchArray(field)[recordIndex]</pre></code>
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
<T, U> U[] fetchArray(Field<T> field, Converter<? super T, U> converter) throws DataAccessException;
/**
* Execute the query and return at most one resulting record as an array
* <p>

View File

@ -40,6 +40,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.Field;
import org.jooq.FutureResult;
@ -126,6 +127,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetch(field, type);
}
@Override
public final <T, U> List<U> fetch(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetch(field, converter);
}
@Override
public final List<?> fetch(int fieldIndex) {
return getDelegate().fetch(fieldIndex);
@ -136,6 +142,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetch(fieldIndex, type);
}
@Override
public final <U> List<U> fetch(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetch(fieldIndex, converter);
}
@Override
public final List<?> fetch(String fieldName) {
return getDelegate().fetch(fieldName);
@ -146,11 +157,26 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetch(fieldName, type);
}
@Override
public final <U> List<U> fetch(String fieldName, Converter<?, U> converter) {
return getDelegate().fetch(fieldName, converter);
}
@Override
public final <T> T fetchOne(Field<T> field) {
return getDelegate().fetchOne(field);
}
@Override
public final <T> T fetchOne(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchOne(field, type);
}
@Override
public final <T, U> U fetchOne(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchOne(field, converter);
}
@Override
public final Object fetchOne(int fieldIndex) {
return getDelegate().fetchOne(fieldIndex);
@ -161,6 +187,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchOne(fieldIndex, type);
}
@Override
public final <U> U fetchOne(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldIndex, converter);
}
@Override
public final Object fetchOne(String fieldName) {
return getDelegate().fetchOne(fieldName);
@ -171,6 +202,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchOne(fieldName, type);
}
@Override
public final <U> U fetchOne(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchOne(fieldName, converter);
}
@Override
public final R fetchOne() {
return getDelegate().fetchOne();
@ -216,6 +252,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchArray(fieldIndex, type);
}
@Override
public final <U> U[] fetchArray(int fieldIndex, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldIndex, converter);
}
@Override
public final Object[] fetchArray(String fieldName) {
return getDelegate().fetchArray(fieldName);
@ -226,11 +267,26 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchArray(fieldName, type);
}
@Override
public final <U> U[] fetchArray(String fieldName, Converter<?, U> converter) {
return getDelegate().fetchArray(fieldName, converter);
}
@Override
public final <T> T[] fetchArray(Field<T> field) {
return getDelegate().fetchArray(field);
}
@Override
public final <T> T[] fetchArray(Field<?> field, Class<? extends T> type) {
return getDelegate().fetchArray(field, type);
}
@Override
public final <T, U> U[] fetchArray(Field<T> field, Converter<? super T, U> converter) {
return getDelegate().fetchArray(field, converter);
}
@Override
public final Object[] fetchOneArray() {
return getDelegate().fetchOneArray();

View File

@ -58,6 +58,7 @@ import java.util.List;
import org.jooq.ArrayRecord;
import org.jooq.Attachable;
import org.jooq.Converter;
import org.jooq.Field;
import org.jooq.FieldProvider;
import org.jooq.Record;
@ -154,12 +155,12 @@ abstract class AbstractRecord extends AbstractStore<Object> implements Record {
}
@Override
public final <T> T getValue(Field<T> field) throws IllegalArgumentException {
public final <T> T getValue(Field<T> field) {
return getValue0(field).getValue();
}
@Override
public final <T> T getValue(Field<T> field, T defaultValue) throws IllegalArgumentException {
public final <T> T getValue(Field<T> field, T defaultValue) {
return getValue0(field).getValue(defaultValue);
}
@ -192,6 +193,11 @@ abstract class AbstractRecord extends AbstractStore<Object> implements Record {
}
}
@Override
public final <T, U> void setValue(Field<T> field, U value, Converter<T, ? super U> converter) {
setValue(field, converter.to(value));
}
final <T> void setValue(Field<T> field, Value<T> value) {
getValues()[getIndex(field)] = value;
}
@ -209,321 +215,354 @@ abstract class AbstractRecord extends AbstractStore<Object> implements Record {
}
@Override
public final String getValueAsString(Field<?> field) throws IllegalArgumentException {
public final String getValueAsString(Field<?> field) {
return getValueAsString(getIndex(field));
}
@Override
public final String getValueAsString(Field<?> field, String defaultValue) throws IllegalArgumentException {
public final String getValueAsString(Field<?> field, String defaultValue) {
return getValueAsString(getIndex(field), defaultValue);
}
@Override
public final Byte getValueAsByte(Field<?> field) throws IllegalArgumentException {
public final Byte getValueAsByte(Field<?> field) {
return getValueAsByte(getIndex(field));
}
@Override
public final Byte getValueAsByte(Field<?> field, Byte defaultValue) throws IllegalArgumentException {
public final Byte getValueAsByte(Field<?> field, Byte defaultValue) {
return getValueAsByte(getIndex(field), defaultValue);
}
@Override
public final Short getValueAsShort(Field<?> field) throws IllegalArgumentException {
public final Short getValueAsShort(Field<?> field) {
return getValueAsShort(getIndex(field));
}
@Override
public final Short getValueAsShort(Field<?> field, Short defaultValue) throws IllegalArgumentException {
public final Short getValueAsShort(Field<?> field, Short defaultValue) {
return getValueAsShort(getIndex(field), defaultValue);
}
@Override
public final Integer getValueAsInteger(Field<?> field) throws IllegalArgumentException {
public final Integer getValueAsInteger(Field<?> field) {
return getValueAsInteger(getIndex(field));
}
@Override
public final Integer getValueAsInteger(Field<?> field, Integer defaultValue) throws IllegalArgumentException {
public final Integer getValueAsInteger(Field<?> field, Integer defaultValue) {
return getValueAsInteger(getIndex(field), defaultValue);
}
@Override
public final Long getValueAsLong(Field<?> field) throws IllegalArgumentException {
public final Long getValueAsLong(Field<?> field) {
return getValueAsLong(getIndex(field));
}
@Override
public final Long getValueAsLong(Field<?> field, Long defaultValue) throws IllegalArgumentException {
public final Long getValueAsLong(Field<?> field, Long defaultValue) {
return getValueAsLong(getIndex(field), defaultValue);
}
@Override
public final BigInteger getValueAsBigInteger(Field<?> field) throws IllegalArgumentException {
public final BigInteger getValueAsBigInteger(Field<?> field) {
return getValueAsBigInteger(getIndex(field));
}
@Override
public final BigInteger getValueAsBigInteger(Field<?> field, BigInteger defaultValue)
throws IllegalArgumentException {
{
return getValueAsBigInteger(getIndex(field), defaultValue);
}
@Override
public final Float getValueAsFloat(Field<?> field) throws IllegalArgumentException {
public final Float getValueAsFloat(Field<?> field) {
return getValueAsFloat(getIndex(field));
}
@Override
public final Float getValueAsFloat(Field<?> field, Float defaultValue) throws IllegalArgumentException {
public final Float getValueAsFloat(Field<?> field, Float defaultValue) {
return getValueAsFloat(getIndex(field), defaultValue);
}
@Override
public final Double getValueAsDouble(Field<?> field) throws IllegalArgumentException {
public final Double getValueAsDouble(Field<?> field) {
return getValueAsDouble(getIndex(field));
}
@Override
public final Double getValueAsDouble(Field<?> field, Double defaultValue) throws IllegalArgumentException {
public final Double getValueAsDouble(Field<?> field, Double defaultValue) {
return getValueAsDouble(getIndex(field), defaultValue);
}
@Override
public final BigDecimal getValueAsBigDecimal(Field<?> field) throws IllegalArgumentException {
public final BigDecimal getValueAsBigDecimal(Field<?> field) {
return getValueAsBigDecimal(getIndex(field));
}
@Override
public final BigDecimal getValueAsBigDecimal(Field<?> field, BigDecimal defaultValue)
throws IllegalArgumentException {
{
return getValueAsBigDecimal(getIndex(field), defaultValue);
}
@Override
public final Boolean getValueAsBoolean(Field<?> field) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(Field<?> field) {
return getValueAsBoolean(getIndex(field));
}
@Override
public final Boolean getValueAsBoolean(Field<?> field, Boolean defaultValue) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(Field<?> field, Boolean defaultValue) {
return getValueAsBoolean(getIndex(field), defaultValue);
}
@Override
public final Timestamp getValueAsTimestamp(Field<?> field) throws IllegalArgumentException {
public final Timestamp getValueAsTimestamp(Field<?> field) {
return getValueAsTimestamp(getIndex(field));
}
@Override
public final Timestamp getValueAsTimestamp(Field<?> field, Timestamp defaultValue) throws IllegalArgumentException {
public final Timestamp getValueAsTimestamp(Field<?> field, Timestamp defaultValue) {
return getValueAsTimestamp(getIndex(field), defaultValue);
}
@Override
public final Date getValueAsDate(Field<?> field) throws IllegalArgumentException {
public final Date getValueAsDate(Field<?> field) {
return getValueAsDate(getIndex(field));
}
@Override
public final Date getValueAsDate(Field<?> field, Date defaultValue) throws IllegalArgumentException {
public final Date getValueAsDate(Field<?> field, Date defaultValue) {
return getValueAsDate(getIndex(field), defaultValue);
}
@Override
public final Time getValueAsTime(Field<?> field) throws IllegalArgumentException {
public final Time getValueAsTime(Field<?> field) {
return getValueAsTime(getIndex(field));
}
@Override
public final Time getValueAsTime(Field<?> field, Time defaultValue) throws IllegalArgumentException {
public final Time getValueAsTime(Field<?> field, Time defaultValue) {
return getValueAsTime(getIndex(field), defaultValue);
}
@Override
public final Object getValue(int index) throws IllegalArgumentException {
public final Object getValue(int index) {
return getValue(getField(index));
}
@Override
public final Object getValue(String fieldName) throws IllegalArgumentException {
public final Object getValue(String fieldName) {
return getValue(getField(fieldName));
}
@SuppressWarnings("unchecked")
@Override
public final Object getValue(String fieldName, Object defaultValue) throws IllegalArgumentException {
public final Object getValue(String fieldName, Object defaultValue) {
return getValue((Field<Object>) getField(fieldName), defaultValue);
}
@Override
public final <A extends ArrayRecord<T>, T> T[] getValueAsArray(Field<A> field) throws IllegalArgumentException {
public final <A extends ArrayRecord<T>, T> T[] getValueAsArray(Field<A> field) {
A result = getValue(field);
return result == null ? null : result.get();
}
@Override
public final <A extends ArrayRecord<T>, T> T[] getValueAsArray(Field<A> field, T[] defaultValue)
throws IllegalArgumentException {
{
final T[] result = getValueAsArray(field);
return result == null ? defaultValue : result;
}
@Override
public final String getValueAsString(String fieldName) throws IllegalArgumentException {
public final String getValueAsString(String fieldName) {
return getValueAsString(getField(fieldName));
}
@Override
public final String getValueAsString(String fieldName, String defaultValue) throws IllegalArgumentException {
public final String getValueAsString(String fieldName, String defaultValue) {
return getValueAsString(getField(fieldName), defaultValue);
}
@Override
public final Byte getValueAsByte(String fieldName) throws IllegalArgumentException {
public final Byte getValueAsByte(String fieldName) {
return getValueAsByte(getField(fieldName));
}
@Override
public final Byte getValueAsByte(String fieldName, Byte defaultValue) throws IllegalArgumentException {
public final Byte getValueAsByte(String fieldName, Byte defaultValue) {
return getValueAsByte(getField(fieldName), defaultValue);
}
@Override
public final Short getValueAsShort(String fieldName) throws IllegalArgumentException {
public final Short getValueAsShort(String fieldName) {
return getValueAsShort(getField(fieldName));
}
@Override
public final Short getValueAsShort(String fieldName, Short defaultValue) throws IllegalArgumentException {
public final Short getValueAsShort(String fieldName, Short defaultValue) {
return getValueAsShort(getField(fieldName), defaultValue);
}
@Override
public final Integer getValueAsInteger(String fieldName) throws IllegalArgumentException {
public final Integer getValueAsInteger(String fieldName) {
return getValueAsInteger(getField(fieldName));
}
@Override
public final Integer getValueAsInteger(String fieldName, Integer defaultValue) throws IllegalArgumentException {
public final Integer getValueAsInteger(String fieldName, Integer defaultValue) {
return getValueAsInteger(getField(fieldName), defaultValue);
}
@Override
public final Long getValueAsLong(String fieldName) throws IllegalArgumentException {
public final Long getValueAsLong(String fieldName) {
return getValueAsLong(getField(fieldName));
}
@Override
public final Long getValueAsLong(String fieldName, Long defaultValue) throws IllegalArgumentException {
public final Long getValueAsLong(String fieldName, Long defaultValue) {
return getValueAsLong(getField(fieldName), defaultValue);
}
@Override
public final BigInteger getValueAsBigInteger(String fieldName) throws IllegalArgumentException {
public final BigInteger getValueAsBigInteger(String fieldName) {
return getValueAsBigInteger(getField(fieldName));
}
@Override
public final BigInteger getValueAsBigInteger(String fieldName, BigInteger defaultValue)
throws IllegalArgumentException {
{
return getValueAsBigInteger(getField(fieldName), defaultValue);
}
@Override
public final Float getValueAsFloat(String fieldName) throws IllegalArgumentException {
public final Float getValueAsFloat(String fieldName) {
return getValueAsFloat(getField(fieldName));
}
@Override
public final Float getValueAsFloat(String fieldName, Float defaultValue) throws IllegalArgumentException {
public final Float getValueAsFloat(String fieldName, Float defaultValue) {
return getValueAsFloat(getField(fieldName), defaultValue);
}
@Override
public final Double getValueAsDouble(String fieldName) throws IllegalArgumentException {
public final Double getValueAsDouble(String fieldName) {
return getValueAsDouble(getField(fieldName));
}
@Override
public final Double getValueAsDouble(String fieldName, Double defaultValue) throws IllegalArgumentException {
public final Double getValueAsDouble(String fieldName, Double defaultValue) {
return getValueAsDouble(getField(fieldName), defaultValue);
}
@Override
public final BigDecimal getValueAsBigDecimal(String fieldName) throws IllegalArgumentException {
public final BigDecimal getValueAsBigDecimal(String fieldName) {
return getValueAsBigDecimal(getField(fieldName));
}
@Override
public final BigDecimal getValueAsBigDecimal(String fieldName, BigDecimal defaultValue)
throws IllegalArgumentException {
{
return getValueAsBigDecimal(getField(fieldName), defaultValue);
}
@Override
public final Boolean getValueAsBoolean(String fieldName) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(String fieldName) {
return getValueAsBoolean(getField(fieldName));
}
@Override
public final Boolean getValueAsBoolean(String fieldName, Boolean defaultValue) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(String fieldName, Boolean defaultValue) {
return getValueAsBoolean(getField(fieldName), defaultValue);
}
@Override
public final Timestamp getValueAsTimestamp(String fieldName) throws IllegalArgumentException {
public final Timestamp getValueAsTimestamp(String fieldName) {
return getValueAsTimestamp(getField(fieldName));
}
@Override
public final Timestamp getValueAsTimestamp(String fieldName, Timestamp defaultValue)
throws IllegalArgumentException {
{
return getValueAsTimestamp(getField(fieldName), defaultValue);
}
@Override
public final Date getValueAsDate(String fieldName) throws IllegalArgumentException {
public final Date getValueAsDate(String fieldName) {
return getValueAsDate(getField(fieldName));
}
@Override
public final Date getValueAsDate(String fieldName, Date defaultValue) throws IllegalArgumentException {
public final Date getValueAsDate(String fieldName, Date defaultValue) {
return getValueAsDate(getField(fieldName), defaultValue);
}
@Override
public final Time getValueAsTime(String fieldName) throws IllegalArgumentException {
public final Time getValueAsTime(String fieldName) {
return getValueAsTime(getField(fieldName));
}
@Override
public final Time getValueAsTime(String fieldName, Time defaultValue) throws IllegalArgumentException {
public final Time getValueAsTime(String fieldName, Time defaultValue) {
return getValueAsTime(getField(fieldName), defaultValue);
}
@Override
public final <T> T getValue(Field<?> field, Class<? extends T> type) throws IllegalArgumentException {
public final <T> T getValue(Field<?> field, Class<? extends T> type) {
return Convert.convert(getValue(field), type);
}
@Override
public final <T> T getValue(Field<?> field, Class<? extends T> type, T defaultValue) throws IllegalArgumentException {
public final <T> T getValue(Field<?> field, Class<? extends T> type, T defaultValue) {
final T result = getValue(field, type);
return result == null ? defaultValue : result;
}
@Override
public final <T> T getValue(String fieldName, Class<? extends T> type) throws IllegalArgumentException {
public final <T> T getValue(String fieldName, Class<? extends T> type) {
return Convert.convert(getValue(fieldName), type);
}
@Override
public final <Z> Z getValue(String fieldName, Class<? extends Z> type, Z defaultValue) throws IllegalArgumentException {
public final <Z> Z getValue(String fieldName, Class<? extends Z> type, Z defaultValue) {
final Z result = getValue(fieldName, type);
return result == null ? defaultValue : result;
}
@Override
public final <T, U> U getValue(Field<T> field, Converter<? super T, U> converter) {
return converter.from(getValue(field));
}
@Override
public final <T, U> U getValue(Field<T> field, Converter<? super T, U> converter, U defaultValue) {
final U result = getValue(field, converter);
return result == null ? defaultValue : result;
}
@Override
public final <U> U getValue(int index, Converter<?, U> converter) {
return Convert.convert(getValue(index), converter);
}
@Override
public final <U> U getValue(int index, Converter<?, U> converter, U defaultValue) {
final U result = getValue(index, converter);
return result == null ? defaultValue : result;
}
@Override
public final <U> U getValue(String fieldName, Converter<?, U> converter) {
return Convert.convert(getValue(fieldName), converter);
}
@Override
public final <U> U getValue(String fieldName, Converter<?, U> converter, U defaultValue) {
final U result = getValue(fieldName, converter);
return result == null ? defaultValue : result;
}
@Override
public final Object[] intoArray() {
return into(Object[].class);

View File

@ -52,6 +52,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.ExecuteContext;
import org.jooq.ExecuteListener;
@ -64,7 +65,6 @@ import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.SQLDialect;
import org.jooq.Table;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.DataTypeException;
import org.jooq.exception.InvalidResultException;
import org.jooq.tools.Convert;
@ -207,7 +207,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
}
@Override
public final ResultSet fetchResultSet() throws DataAccessException {
public final ResultSet fetchResultSet() {
return fetchLazy().resultSet();
}
@ -217,7 +217,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
}
@Override
public final Cursor<R> fetchLazy(int fetchSize) throws DataAccessException {
public final Cursor<R> fetchLazy(int fetchSize) {
lazy = true;
size = fetchSize;
@ -247,10 +247,15 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
}
@Override
public final <T> List<T> fetch(Field<?> field, Class<? extends T> type) throws DataAccessException {
public final <T> List<T> fetch(Field<?> field, Class<? extends T> type) {
return fetch().getValues(field, type);
}
@Override
public final <T, U> List<U> fetch(Field<T> field, Converter<? super T, U> converter) {
return fetch().getValues(field, converter);
}
@Override
public final List<?> fetch(int fieldIndex) {
return fetch().getValues(fieldIndex);
@ -261,6 +266,11 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().getValues(fieldIndex, type);
}
@Override
public final <U> List<U> fetch(int fieldIndex, Converter<?, U> converter) {
return fetch().getValues(fieldIndex, converter);
}
@Override
public final List<?> fetch(String fieldName) {
return fetch().getValues(fieldName);
@ -271,12 +281,27 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().getValues(fieldName, type);
}
@Override
public final <U> List<U> fetch(String fieldName, Converter<?, U> converter) {
return fetch().getValues(fieldName, converter);
}
@Override
public final <T> T fetchOne(Field<T> field) {
R record = fetchOne();
return record == null ? null : record.getValue(field);
}
@Override
public final <T> T fetchOne(Field<?> field, Class<? extends T> type) {
return Convert.convert(fetchOne(field), type);
}
@Override
public final <T, U> U fetchOne(Field<T> field, Converter<? super T, U> converter) {
return Convert.convert(fetchOne(field), converter);
}
@Override
public final Object fetchOne(int fieldIndex) {
R record = fetchOne();
@ -288,6 +313,11 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return Convert.convert(fetchOne(fieldIndex), type);
}
@Override
public final <U> U fetchOne(int fieldIndex, Converter<?, U> converter) {
return Convert.convert(fetchOne(fieldIndex), converter);
}
@Override
public final Object fetchOne(String fieldName) {
R record = fetchOne();
@ -299,6 +329,11 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return Convert.convert(fetchOne(fieldName), type);
}
@Override
public final <U> U fetchOne(String fieldName, Converter<?, U> converter) {
return Convert.convert(fetchOne(fieldName), converter);
}
@Override
public final R fetchOne() {
Result<R> r = fetch();
@ -393,6 +428,12 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return (T[]) Convert.convertArray(fetchArray(fieldIndex), type);
}
@SuppressWarnings("cast")
@Override
public final <U> U[] fetchArray(int fieldIndex, Converter<?, U> converter) {
return (U[]) Convert.convertArray(fetchArray(fieldIndex), converter);
}
@Override
public final Object[] fetchArray(String fieldName) {
return fetch(fieldName).toArray();
@ -404,12 +445,40 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return (T[]) Convert.convertArray(fetchArray(fieldName), type);
}
@SuppressWarnings("cast")
@Override
public final <U> U[] fetchArray(String fieldName, Converter<?, U> converter) {
return (U[]) Convert.convertArray(fetchArray(fieldName), converter);
}
@SuppressWarnings("unchecked")
@Override
public final <T> T[] fetchArray(Field<T> field) {
return fetch(field).toArray((T[]) Array.newInstance(field.getType(), 0));
}
@SuppressWarnings("unchecked")
@Override
public final <T> T[] fetchArray(Field<?> field, Class<? extends T> type) {
return (T[]) Convert.convertArray(fetchArray(field), type);
}
@SuppressWarnings("cast")
@Override
public final <T, U> U[] fetchArray(Field<T> field, Converter<? super T, U> converter) {
return (U[]) Convert.convertArray(fetchArray(field), converter);
}
/**
* Subclasses may override this method
* <p>
* {@inheritDoc}
*/
@Override
public Class<? extends R> getRecordType() {
return null;
}
@Override
public final Object[] fetchOneArray() {
return fetchOne().intoArray();
@ -421,7 +490,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
}
@Override
public final <Z extends Record> Result<Z> fetchInto(Table<Z> table) throws DataAccessException {
public final <Z extends Record> Result<Z> fetchInto(Table<Z> table) {
return fetch().into(table);
}

View File

@ -72,7 +72,7 @@ abstract class AbstractStore<T> implements Store<T>, AttachableInternal {
// -------------------------------------------------------------------------
@Override
public final <I> I internalAPI(Class<I> internalType) throws ClassCastException {
public final <I> I internalAPI(Class<I> internalType) {
return internalType.cast(this);
}
@ -98,161 +98,161 @@ abstract class AbstractStore<T> implements Store<T>, AttachableInternal {
// -------------------------------------------------------------------------
@Override
public final T getValue(int index, T defaultValue) throws IllegalArgumentException {
public final T getValue(int index, T defaultValue) {
final T result = getValue(index);
return result == null ? defaultValue : result;
}
@Override
public final BigDecimal getValueAsBigDecimal(int index) throws IllegalArgumentException {
public final BigDecimal getValueAsBigDecimal(int index) {
return Convert.convert(getValue(index), BigDecimal.class);
}
@Override
public final BigDecimal getValueAsBigDecimal(int index, BigDecimal defaultValue) throws IllegalArgumentException {
public final BigDecimal getValueAsBigDecimal(int index, BigDecimal defaultValue) {
final BigDecimal result = getValueAsBigDecimal(index);
return result == null ? defaultValue : result;
}
@Override
public final Boolean getValueAsBoolean(int index) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(int index) {
return Convert.convert(getValue(index), Boolean.class);
}
@Override
public final Boolean getValueAsBoolean(int index, Boolean defaultValue) throws IllegalArgumentException {
public final Boolean getValueAsBoolean(int index, Boolean defaultValue) {
final Boolean result = getValueAsBoolean(index);
return result == null ? defaultValue : result;
}
@Override
public final BigInteger getValueAsBigInteger(int index) throws IllegalArgumentException {
public final BigInteger getValueAsBigInteger(int index) {
return Convert.convert(getValue(index), BigInteger.class);
}
@Override
public final BigInteger getValueAsBigInteger(int index, BigInteger defaultValue) throws IllegalArgumentException {
public final BigInteger getValueAsBigInteger(int index, BigInteger defaultValue) {
final BigInteger result = getValueAsBigInteger(index);
return result == null ? defaultValue : result;
}
@Override
public final Byte getValueAsByte(int index) throws IllegalArgumentException {
public final Byte getValueAsByte(int index) {
return Convert.convert(getValue(index), Byte.class);
}
@Override
public final Byte getValueAsByte(int index, Byte defaultValue) throws IllegalArgumentException {
public final Byte getValueAsByte(int index, Byte defaultValue) {
final Byte result = getValueAsByte(index);
return result == null ? defaultValue : result;
}
@Override
public final Date getValueAsDate(int index) throws IllegalArgumentException {
public final Date getValueAsDate(int index) {
return Convert.convert(getValue(index), Date.class);
}
@Override
public final Date getValueAsDate(int index, Date defaultValue) throws IllegalArgumentException {
public final Date getValueAsDate(int index, Date defaultValue) {
final Date result = getValueAsDate(index);
return result == null ? defaultValue : result;
}
@Override
public final Double getValueAsDouble(int index) throws IllegalArgumentException {
public final Double getValueAsDouble(int index) {
return Convert.convert(getValue(index), Double.class);
}
@Override
public final Double getValueAsDouble(int index, Double defaultValue) throws IllegalArgumentException {
public final Double getValueAsDouble(int index, Double defaultValue) {
final Double result = getValueAsDouble(index);
return result == null ? defaultValue : result;
}
@Override
public final Float getValueAsFloat(int index) throws IllegalArgumentException {
public final Float getValueAsFloat(int index) {
return Convert.convert(getValue(index), Float.class);
}
@Override
public final Float getValueAsFloat(int index, Float defaultValue) throws IllegalArgumentException {
public final Float getValueAsFloat(int index, Float defaultValue) {
final Float result = getValueAsFloat(index);
return result == null ? defaultValue : result;
}
@Override
public final Integer getValueAsInteger(int index) throws IllegalArgumentException {
public final Integer getValueAsInteger(int index) {
return Convert.convert(getValue(index), Integer.class);
}
@Override
public final Integer getValueAsInteger(int index, Integer defaultValue) throws IllegalArgumentException {
public final Integer getValueAsInteger(int index, Integer defaultValue) {
final Integer result = getValueAsInteger(index);
return result == null ? defaultValue : result;
}
@Override
public final Long getValueAsLong(int index) throws IllegalArgumentException {
public final Long getValueAsLong(int index) {
return Convert.convert(getValue(index), Long.class);
}
@Override
public final Long getValueAsLong(int index, Long defaultValue) throws IllegalArgumentException {
public final Long getValueAsLong(int index, Long defaultValue) {
final Long result = getValueAsLong(index);
return result == null ? defaultValue : result;
}
@Override
public final Short getValueAsShort(int index) throws IllegalArgumentException {
public final Short getValueAsShort(int index) {
return Convert.convert(getValue(index), Short.class);
}
@Override
public final Short getValueAsShort(int index, Short defaultValue) throws IllegalArgumentException {
public final Short getValueAsShort(int index, Short defaultValue) {
final Short result = getValueAsShort(index);
return result == null ? defaultValue : result;
}
@Override
public final String getValueAsString(int index) throws IllegalArgumentException {
public final String getValueAsString(int index) {
return Convert.convert(getValue(index), String.class);
}
@Override
public final String getValueAsString(int index, String defaultValue) throws IllegalArgumentException {
public final String getValueAsString(int index, String defaultValue) {
final String result = getValueAsString(index);
return result == null ? defaultValue : result;
}
@Override
public final Time getValueAsTime(int index) throws IllegalArgumentException {
public final Time getValueAsTime(int index) {
return Convert.convert(getValue(index), Time.class);
}
@Override
public final Time getValueAsTime(int index, Time defaultValue) throws IllegalArgumentException {
public final Time getValueAsTime(int index, Time defaultValue) {
final Time result = getValueAsTime(index);
return result == null ? defaultValue : result;
}
@Override
public final Timestamp getValueAsTimestamp(int index) throws IllegalArgumentException {
public final Timestamp getValueAsTimestamp(int index) {
return Convert.convert(getValue(index), Timestamp.class);
}
@Override
public final Timestamp getValueAsTimestamp(int index, Timestamp defaultValue) throws IllegalArgumentException {
public final Timestamp getValueAsTimestamp(int index, Timestamp defaultValue) {
final Timestamp result = getValueAsTimestamp(index);
return result == null ? defaultValue : result;
}
@Override
public final <Z> Z getValue(int index, Class<? extends Z> type) throws IllegalArgumentException {
public final <Z> Z getValue(int index, Class<? extends Z> type) {
return Convert.convert(getValue(index), type);
}
@Override
public final <Z> Z getValue(int index, Class<? extends Z> type, Z defaultValue) throws IllegalArgumentException {
public final <Z> Z getValue(int index, Class<? extends Z> type, Z defaultValue) {
final Z result = getValue(index, type);
return result == null ? defaultValue : result;
}

View File

@ -65,6 +65,7 @@ import org.jooq.ArrayRecord;
import org.jooq.Attachable;
import org.jooq.AttachableInternal;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.EnumType;
import org.jooq.Field;
import org.jooq.FieldProvider;
@ -628,6 +629,11 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return Convert.convert(getValues(field), type);
}
@Override
public final <T, U> List<U> getValues(Field<T> field, Converter<? super T, U> converter) {
return Convert.convert(getValues(field), converter);
}
@Override
public final List<?> getValues(int fieldIndex) {
return getValues(getField(fieldIndex));
@ -638,6 +644,11 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return Convert.convert(getValues(fieldIndex), type);
}
@Override
public final <U> List<U> getValues(int fieldIndex, Converter<?, U> converter) {
return Convert.convert(getValues(fieldIndex), converter);
}
@Override
public final List<?> getValues(String fieldName) {
return getValues(getField(fieldName));
@ -648,6 +659,11 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return Convert.convert(getValues(fieldName), type);
}
@Override
public final <U> List<U> getValues(String fieldName, Converter<?, U> converter) {
return Convert.convert(getValues(fieldName), converter);
}
@Override
public final List<BigDecimal> getValuesAsBigDecimal(Field<?> field) {
List<BigDecimal> result = new ArrayList<BigDecimal>();

View File

@ -54,6 +54,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jooq.Converter;
import org.jooq.EnumType;
import org.jooq.exception.DataTypeException;
import org.jooq.tools.unsigned.UByte;
@ -63,6 +64,12 @@ import org.jooq.tools.unsigned.UShort;
/**
* Utility methods for type conversions
* <p>
* This class provides less type-safety than the general jOOQ API methods. For
* instance, it accepts arbitrary {@link Converter} objects in methods like
* {@link #convert(List, Converter)} and {@link #convert(Object, Class)}, trying
* to retrofit the <code>Object</code> argument to the type provided in
* {@link Converter#fromType()} before performing the actual conversion.
*
* @author Lukas Eder
*/
@ -103,6 +110,35 @@ public final class Convert {
FALSE_VALUES = Collections.unmodifiableSet(falseValues);
}
/**
* Convert an array into another one using a converter
* <p>
* This uses {@link #convertArray(Object[], Class)} to convert the array to
* an array of {@link Converter#fromType()} first, before converting that
* array again to {@link Converter#toType()}
*
* @param from The array to convert
* @param converter The data type converter
* @return A converted array
* @throws DataTypeException - When the conversion is not possible
*/
@SuppressWarnings("unchecked")
public static <U> U[] convertArray(Object[] from, Converter<?, U> converter) throws DataTypeException {
if (from == null) {
return null;
}
else {
Object[] arrayOfT = convertArray(from, converter.fromType());
Object[] arrayOfU = (Object[]) Array.newInstance(converter.toType(), from.length);
for (int i = 0; i < arrayOfT.length; i++) {
arrayOfU[i] = convert(arrayOfT[i], converter);
}
return (U[]) arrayOfU;
}
}
/**
* Convert an array into another one by these rules
* <p>
@ -151,6 +187,26 @@ public final class Convert {
}
}
/**
* Convert an object to a type.
*
* @param from The source object
* @param converter The data type converter
* @return The target type object
* @throws DataTypeException - When the conversion is not possible
*/
public static <U> U convert(Object from, Converter<?, U> converter) throws DataTypeException {
return convert0(from, converter);
}
/**
* Conversion type-safety
*/
private static <T, U> U convert0(Object from, Converter<T, U> converter) throws DataTypeException {
ConvertAll<T> all = new ConvertAll<T>(converter.fromType());
return converter.from(all.from(from));
}
/**
* Convert an object to a type. These are the conversion rules:
* <ul>
@ -198,172 +254,8 @@ public final class Convert {
* @return The converted object
* @throws DataTypeException - When the conversion is not possible
*/
@SuppressWarnings("unchecked")
public static <T> T convert(Object from, Class<? extends T> toClass) throws DataTypeException {
if (from == null) {
// [#936] If types are converted to primitives, the result must not
// be null. Return the default value instead
if (toClass.isPrimitive()) {
// Characters default to the "zero" character
if (toClass == char.class) {
return (T) Character.valueOf((char) 0);
}
// All others can be converted from (int) 0
else {
return convert(0, toClass);
}
}
else {
return null;
}
}
else {
final Class<?> fromClass = from.getClass();
// No conversion
if (toClass == fromClass) {
return (T) from;
}
// [#1155] Do this early: identity-conversion into Object
else if (toClass == Object.class) {
return (T) from;
}
else if (fromClass == byte[].class) {
// This may not make much sense. Any other options?
return convert(Arrays.toString((byte[]) from), toClass);
}
else if (fromClass.isArray()) {
return (T) convertArray((Object[]) from, toClass);
}
// All types can be converted into String
else if (toClass == String.class) {
if (from instanceof EnumType) {
return (T) ((EnumType) from).getLiteral();
}
return (T) from.toString();
}
// Various number types are converted between each other via String
else if (toClass == Byte.class || toClass == byte.class) {
return (T) Byte.valueOf(new BigDecimal(from.toString().trim()).byteValue());
}
else if (toClass == Short.class || toClass == short.class) {
return (T) Short.valueOf(new BigDecimal(from.toString().trim()).shortValue());
}
else if (toClass == Integer.class || toClass == int.class) {
return (T) Integer.valueOf(new BigDecimal(from.toString().trim()).intValue());
}
else if (toClass == Long.class || toClass == long.class) {
if (java.util.Date.class.isAssignableFrom(fromClass)) {
return (T) Long.valueOf(((java.util.Date) from).getTime());
}
else {
return (T) Long.valueOf(new BigDecimal(from.toString().trim()).longValue());
}
}
// ... this also includes unsigned number types
else if (toClass == UByte.class) {
return (T) ubyte(new BigDecimal(from.toString().trim()).shortValue());
}
else if (toClass == UShort.class) {
return (T) ushort(new BigDecimal(from.toString().trim()).intValue());
}
else if (toClass == UInteger.class) {
return (T) uint(new BigDecimal(from.toString().trim()).longValue());
}
else if (toClass == ULong.class) {
if (java.util.Date.class.isAssignableFrom(fromClass)) {
return (T) ulong(((java.util.Date) from).getTime());
}
else {
return (T) ulong(new BigDecimal(from.toString().trim()).toBigInteger().toString());
}
}
// ... and floating point / fixed point types
else if (toClass == Float.class || toClass == float.class) {
return (T) Float.valueOf(from.toString().trim());
}
else if (toClass == Double.class || toClass == double.class) {
return (T) Double.valueOf(from.toString().trim());
}
else if (toClass == BigDecimal.class) {
return (T) new BigDecimal(from.toString().trim());
}
else if (toClass == BigInteger.class) {
return (T) new BigDecimal(from.toString().trim()).toBigInteger();
}
else if (toClass == Boolean.class || toClass == boolean.class) {
String s = from.toString().toLowerCase().trim();
if (TRUE_VALUES.contains(s)) {
return (T) Boolean.TRUE;
}
else if (FALSE_VALUES.contains(s)) {
return (T) Boolean.FALSE;
}
else {
return null;
}
}
else if (toClass == Character.class || toClass == char.class) {
if (from.toString().length() != 1) {
throw fail(from, toClass);
}
return (T) Character.valueOf(from.toString().charAt(0));
}
// Date types can be converted among each other
else if (java.util.Date.class.isAssignableFrom(fromClass)) {
return toDate(((java.util.Date) from).getTime(), toClass);
}
// Long may also be converted into a date type
else if ((fromClass == Long.class || fromClass == long.class) && java.util.Date.class.isAssignableFrom(toClass)) {
return toDate((Long) from, toClass);
}
}
throw fail(from, toClass);
}
/**
* Convert a long timestamp to any date type
*/
@SuppressWarnings("unchecked")
private static <T> T toDate(long time, Class<T> toClass) {
if (toClass == Date.class) {
return (T) new Date(time);
}
else if (toClass == Time.class) {
return (T) new Time(time);
}
else if (toClass == Timestamp.class) {
return (T) new Timestamp(time);
}
else if (toClass == java.util.Date.class) {
return (T) new java.util.Date(time);
}
else if (toClass == Calendar.class) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
return (T) calendar;
}
throw fail(time, toClass);
}
private static DataTypeException fail(Object from, Class<?> toClass) {
return new DataTypeException("Cannot convert from " + from + " (" + from.getClass() + ") to " + toClass);
return convert(from, new ConvertAll<T>(toClass));
}
/**
@ -377,14 +269,235 @@ public final class Convert {
* @see #convert(Object, Class)
*/
public static <T> List<T> convert(List<?> list, Class<? extends T> type) throws DataTypeException {
List<T> result = new ArrayList<T>();
return convert(list, new ConvertAll<T>(type));
}
/**
* Convert a list of objects to a list of <code>T</code>, using
* {@link #convert(Object, Converter)}
*
* @param list The list of objects
* @param converter The data type converter
* @return The list of converted objects
* @throws DataTypeException - When the conversion is not possible
* @see #convert(Object, Converter)
*/
public static <U> List<U> convert(List<?> list, Converter<?, U> converter) throws DataTypeException {
return convert0(list, converter);
}
/**
* Type safe conversion
*/
private static <T, U> List<U> convert0(List<?> list, Converter<T, U> converter) throws DataTypeException {
ConvertAll<T> all = new ConvertAll<T>(converter.fromType());
List<U> result = new ArrayList<U>();
for (Object o : list) {
result.add(convert(o, type));
result.add(convert(all.from(o), converter));
}
return result;
}
/**
* No instances
*/
private Convert() {}
/**
* The converter to convert them all.
*/
private static class ConvertAll<U> implements Converter<Object, U> {
private final Class<? extends U> toClass;
ConvertAll(Class<? extends U> toClass) {
this.toClass = toClass;
}
@SuppressWarnings("unchecked")
@Override
public U from(Object from) {
if (from == null) {
// [#936] If types are converted to primitives, the result must not
// be null. Return the default value instead
if (toClass.isPrimitive()) {
// Characters default to the "zero" character
if (toClass == char.class) {
return (U) Character.valueOf((char) 0);
}
// All others can be converted from (int) 0
else {
return convert(0, toClass);
}
}
else {
return null;
}
}
else {
final Class<?> fromClass = from.getClass();
// No conversion
if (toClass == fromClass) {
return (U) from;
}
// [#1155] Do this early: identity-conversion into Object
else if (toClass == Object.class) {
return (U) from;
}
else if (fromClass == byte[].class) {
// This may not make much sense. Any other options?
return convert(Arrays.toString((byte[]) from), toClass);
}
else if (fromClass.isArray()) {
return (U) convertArray((Object[]) from, toClass);
}
// All types can be converted into String
else if (toClass == String.class) {
if (from instanceof EnumType) {
return (U) ((EnumType) from).getLiteral();
}
return (U) from.toString();
}
// Various number types are converted between each other via String
else if (toClass == Byte.class || toClass == byte.class) {
return (U) Byte.valueOf(new BigDecimal(from.toString().trim()).byteValue());
}
else if (toClass == Short.class || toClass == short.class) {
return (U) Short.valueOf(new BigDecimal(from.toString().trim()).shortValue());
}
else if (toClass == Integer.class || toClass == int.class) {
return (U) Integer.valueOf(new BigDecimal(from.toString().trim()).intValue());
}
else if (toClass == Long.class || toClass == long.class) {
if (java.util.Date.class.isAssignableFrom(fromClass)) {
return (U) Long.valueOf(((java.util.Date) from).getTime());
}
else {
return (U) Long.valueOf(new BigDecimal(from.toString().trim()).longValue());
}
}
// ... this also includes unsigned number types
else if (toClass == UByte.class) {
return (U) ubyte(new BigDecimal(from.toString().trim()).shortValue());
}
else if (toClass == UShort.class) {
return (U) ushort(new BigDecimal(from.toString().trim()).intValue());
}
else if (toClass == UInteger.class) {
return (U) uint(new BigDecimal(from.toString().trim()).longValue());
}
else if (toClass == ULong.class) {
if (java.util.Date.class.isAssignableFrom(fromClass)) {
return (U) ulong(((java.util.Date) from).getTime());
}
else {
return (U) ulong(new BigDecimal(from.toString().trim()).toBigInteger().toString());
}
}
// ... and floating point / fixed point types
else if (toClass == Float.class || toClass == float.class) {
return (U) Float.valueOf(from.toString().trim());
}
else if (toClass == Double.class || toClass == double.class) {
return (U) Double.valueOf(from.toString().trim());
}
else if (toClass == BigDecimal.class) {
return (U) new BigDecimal(from.toString().trim());
}
else if (toClass == BigInteger.class) {
return (U) new BigDecimal(from.toString().trim()).toBigInteger();
}
else if (toClass == Boolean.class || toClass == boolean.class) {
String s = from.toString().toLowerCase().trim();
if (TRUE_VALUES.contains(s)) {
return (U) Boolean.TRUE;
}
else if (FALSE_VALUES.contains(s)) {
return (U) Boolean.FALSE;
}
else {
return null;
}
}
else if (toClass == Character.class || toClass == char.class) {
if (from.toString().length() != 1) {
throw fail(from, toClass);
}
return (U) Character.valueOf(from.toString().charAt(0));
}
// Date types can be converted among each other
else if (java.util.Date.class.isAssignableFrom(fromClass)) {
return toDate(((java.util.Date) from).getTime(), toClass);
}
// Long may also be converted into a date type
else if ((fromClass == Long.class || fromClass == long.class) && java.util.Date.class.isAssignableFrom(toClass)) {
return toDate((Long) from, toClass);
}
}
throw fail(from, toClass);
}
@Override
public Object to(U to) {
return to;
}
@Override
public Class<Object> fromType() {
return Object.class;
}
@Override
public Class<U> toType() {
return (Class<U>) toClass;
}
/**
* Convert a long timestamp to any date type
*/
@SuppressWarnings("unchecked")
private static <X> X toDate(long time, Class<X> toClass) {
if (toClass == Date.class) {
return (X) new Date(time);
}
else if (toClass == Time.class) {
return (X) new Time(time);
}
else if (toClass == Timestamp.class) {
return (X) new Timestamp(time);
}
else if (toClass == java.util.Date.class) {
return (X) new java.util.Date(time);
}
else if (toClass == Calendar.class) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
return (X) calendar;
}
throw fail(time, toClass);
}
private static DataTypeException fail(Object from, Class<?> toClass) {
return new DataTypeException("Cannot convert from " + from + " (" + from.getClass() + ") to " + toClass);
}
}
}