2017-05-16 16:56:53 -04:00
package com.moparisthebest.jdbc ;
import com.moparisthebest.classgen.Compiler ;
2017-05-27 23:54:22 -04:00
import java.io.IOException ;
2017-05-16 16:56:53 -04:00
import java.lang.reflect.AccessibleObject ;
import java.lang.reflect.Field ;
import java.lang.reflect.Method ;
2017-06-18 21:58:55 -04:00
import java.lang.reflect.Modifier ;
2017-05-16 16:56:53 -04:00
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.util.Calendar ;
2017-06-18 21:58:55 -04:00
import java.util.HashMap ;
import java.util.LinkedHashMap ;
2017-05-16 16:56:53 -04:00
import java.util.Map ;
2017-06-18 21:58:55 -04:00
import java.util.concurrent.ConcurrentHashMap ;
2017-05-16 16:56:53 -04:00
/ * *
2017-05-17 11:18:58 -04:00
* Map a ResultSet row to an Object . This mapper generates / compiles / executes java code to perform the mapping .
*
* @author Travis Burtrum ( modifications from beehive )
* @author Travis Burtrum
* @see RowToObjectMapper for most details , will document here where this differs
* < p >
* Usage differences :
* 1 . Reflection can set non - public or final fields directly , direct java code cannot , so DTOs like that will result in
2017-06-18 21:58:55 -04:00
* a compilation and therefore mapping error , unless the Cache sent in has allowReflection = true which will use reflection
* for these Fields in the generated code .
2017-05-18 14:26:23 -04:00
* /
2017-05-17 17:32:48 -04:00
public class CompilingRowToObjectMapper < K , T > extends RowToObjectMapper < K , T > {
2017-05-18 14:26:23 -04:00
// do not remove, used from generated classes
2017-05-17 17:32:48 -04:00
public static final String firstColumnError = " Cannot call getFirstColumn when mapKeyType is null! " ;
2017-05-16 16:56:53 -04:00
protected final Compiler compiler ;
2017-05-17 17:32:48 -04:00
protected final ResultSetToObject < K , T > resultSetToObject ;
2017-05-16 16:56:53 -04:00
2017-06-07 20:30:58 -04:00
protected String _calendarName = null ;
2017-06-18 21:58:55 -04:00
protected int reflectionFieldIndex = - 1 ;
protected boolean allowReflection = false ;
public CompilingRowToObjectMapper ( final Compiler compiler , final Cache cache , ResultSet resultSet , Class < T > returnTypeClass , Calendar cal , Class < ? > mapValType , Class < K > mapKeyType ) {
2017-05-18 14:26:23 -04:00
this ( compiler , cache , resultSet , returnTypeClass , cal , mapValType , mapKeyType , false ) ;
}
2017-06-18 21:58:55 -04:00
public CompilingRowToObjectMapper ( final Compiler compiler , final Cache cache , ResultSet resultSet , Class < T > returnTypeClass , Calendar cal , Class < ? > mapValType , Class < K > mapKeyType , final boolean caseInsensitiveMap ) {
2017-05-18 14:26:23 -04:00
super ( resultSet , returnTypeClass , cal , mapValType , mapKeyType , caseInsensitiveMap ) ;
2017-05-16 16:56:53 -04:00
this . compiler = compiler ;
try {
2017-06-07 20:30:58 -04:00
final CompilingRowToObjectMapper . ResultSetKey keys = new CompilingRowToObjectMapper . ResultSetKey ( super . getKeysFromResultSet ( ) , _returnTypeClass , _mapKeyType , cal ! = null ) ;
2017-05-16 16:56:53 -04:00
//System.out.printf("keys: %s\n", keys);
@SuppressWarnings ( " unchecked " )
2017-06-18 21:58:55 -04:00
final ResultSetToObject < K , T > resultSetToObject = ( ResultSetToObject < K , T > ) cache . cache . get ( keys ) ;
2017-05-16 16:56:53 -04:00
if ( resultSetToObject = = null ) {
//System.out.printf("cache miss, keys: %s\n", keys);
// generate and put into cache
2017-06-07 20:30:58 -04:00
if ( keys . hasCalendar )
_calendarName = " cal " ;
2017-06-18 21:58:55 -04:00
allowReflection = cache . allowReflection ;
cache . cache . put ( keys , this . resultSetToObject = genClass ( ) ) ;
2017-05-16 16:56:53 -04:00
this . keys = null ;
this . _fields = null ;
this . _fieldTypes = null ;
2017-05-17 13:07:08 -04:00
this . constructor = null ;
2017-05-16 16:56:53 -04:00
} else {
//System.out.printf("cache hit, keys: %s\n", keys);
// load from cache
this . resultSetToObject = resultSetToObject ;
}
} catch ( SQLException e ) {
throw new MapperException ( " CachingRowToObjectMapper: SQLException: " + e . getMessage ( ) , e ) ;
2017-05-27 23:54:22 -04:00
} catch ( IOException e ) {
throw new MapperException ( " CachingRowToObjectMapper: IOException (should never happen?): " + e . getMessage ( ) , e ) ;
2017-05-16 16:56:53 -04:00
}
}
2017-05-27 23:54:22 -04:00
public CompilingRowToObjectMapper ( final String [ ] keys , Class < T > returnTypeClass , Calendar cal , Class < ? > mapValType , Class < K > mapKeyType ) {
super ( keys , null , returnTypeClass , cal , mapValType , mapKeyType , false ) ;
this . compiler = null ;
this . resultSetToObject = null ;
}
2017-05-16 16:56:53 -04:00
@Override
2017-05-17 17:32:48 -04:00
public T mapRowToReturnType ( ) throws SQLException {
return resultSetToObject . toObject ( _resultSet , _cal ) ;
2017-05-16 16:56:53 -04:00
}
2017-05-17 17:32:48 -04:00
@Override
public K getMapKey ( ) throws SQLException {
return resultSetToObject . getFirstColumn ( _resultSet , _cal ) ;
}
2017-05-17 13:49:36 -04:00
2017-06-08 23:02:12 -04:00
@Override
public T toObject ( final ResultSet rs , final Calendar cal ) throws SQLException {
return resultSetToObject . toObject ( rs , cal ) ;
}
@Override
public com . moparisthebest . jdbc . util . ResultSetToObject < T > getResultSetToObject ( ) {
return resultSetToObject ;
}
2017-05-16 16:56:53 -04:00
@Override
protected String [ ] getKeysFromResultSet ( ) throws SQLException {
if ( keys = = null )
throw new MapperException ( " not supported here " ) ;
return keys ;
}
@Override
protected void getFieldMappings ( ) throws SQLException {
throw new MapperException ( " not supported here " ) ;
}
2017-06-08 23:02:12 -04:00
public interface ResultSetToObject < K , T > extends com . moparisthebest . jdbc . util . ResultSetToObject < T > {
2017-05-17 17:32:48 -04:00
K getFirstColumn ( final ResultSet rs , final Calendar cal ) throws SQLException ;
2017-05-16 16:56:53 -04:00
T toObject ( final ResultSet rs , final Calendar cal ) throws SQLException ;
}
2017-06-18 21:58:55 -04:00
public static class Cache {
private final Map < CompilingRowToObjectMapper . ResultSetKey , ResultSetToObject < ? , ? > > cache ;
private final boolean allowReflection ;
public Cache ( final Map < ResultSetKey , ResultSetToObject < ? , ? > > cache , final boolean allowReflection ) {
if ( cache = = null )
throw new NullPointerException ( " cache cannot be null " ) ;
this . cache = cache ;
this . allowReflection = allowReflection ;
}
public Cache ( final Map < ResultSetKey , ResultSetToObject < ? , ? > > cache ) {
this ( cache , false ) ;
}
public Cache ( ) {
this ( new HashMap < CompilingRowToObjectMapper . ResultSetKey , ResultSetToObject < ? , ? > > ( ) ) ;
}
public Cache ( final boolean allowReflection ) {
this ( new HashMap < CompilingRowToObjectMapper . ResultSetKey , ResultSetToObject < ? , ? > > ( ) , allowReflection ) ;
}
}
2017-05-16 16:56:53 -04:00
protected String typeFromName ( final Class < ? > type ) {
2017-05-17 17:32:48 -04:00
if ( type = = null )
return " Object " ;
2017-05-17 15:45:45 -04:00
if ( _columnCount = = 1 & & type . isPrimitive ( ) ) {
// need the object equivalent here, what is the best way? this works, isn't pretty...
if ( type . equals ( Character . TYPE ) )
return " Character " ;
if ( type . equals ( Integer . TYPE ) )
return " Integer " ;
final char [ ] name = type . getName ( ) . toCharArray ( ) ;
name [ 0 ] = Character . toUpperCase ( name [ 0 ] ) ;
return new String ( name ) ;
} else if ( returnMap | | componentType = = null ) {
2017-05-17 11:18:58 -04:00
return type . getName ( ) ;
2017-05-17 15:45:45 -04:00
} else {
2017-05-17 11:18:58 -04:00
// an array, annoying syntax
final String name = type . getName ( ) ;
final char charType = name . charAt ( 1 ) ;
switch ( charType ) {
case 'L' :
return name . substring ( 2 , name . length ( ) - 1 ) + " [] " ;
case 'Z' :
return " boolean[] " ;
case 'B' :
return " byte[] " ;
case 'C' :
return " char[] " ;
case 'D' :
return " double[] " ;
case 'F' :
return " float[] " ;
case 'I' :
return " int[] " ;
case 'J' :
return " long[] " ;
case 'S' :
return " short[] " ;
case '[' :
default :
throw new MapperException ( " only supports single dimensional array " ) ;
}
}
2017-05-16 16:56:53 -04:00
}
2017-06-07 02:43:46 -04:00
public static String escapeMapKeyString ( final String s ) {
2017-05-16 16:56:53 -04:00
// todo: escape key string, newlines, double quotes, backslashes...
2017-05-17 11:18:58 -04:00
// actually it seems like those wouldn't be valid SQL column names, so we won't bother until we hear different...
return '"' + s + '"' ;
2017-05-16 16:56:53 -04:00
}
// code generation down here
2017-05-27 23:54:22 -04:00
protected ResultSetToObject < K , T > genClass ( ) throws IOException {
2017-05-16 16:56:53 -04:00
final String className = " CompilingMapper " ;
final String tType = typeFromName ( _returnTypeClass ) ;
2017-05-17 17:32:48 -04:00
final String kType = typeFromName ( _mapKeyType ) ;
2017-05-16 16:56:53 -04:00
final String header =
" import static com.moparisthebest.jdbc.util.ResultSetUtil.*; \ n \ n " +
" public final class " + className +
2017-05-17 17:32:48 -04:00
" implements com.moparisthebest.jdbc.CompilingRowToObjectMapper.ResultSetToObject< " + kType + " , " + tType + " > { \ n " +
2017-05-16 16:56:53 -04:00
" public " + tType + " toObject(final java.sql.ResultSet rs, final java.util.Calendar cal) throws java.sql.SQLException { \ n " ;
2017-05-17 17:32:48 -04:00
final String footer = " ; \ n } \ n " +
2017-05-16 16:56:53 -04:00
" } \ n " ;
final StringBuilder java = new StringBuilder ( header ) ;
//java.append("return null;\n");
gen ( java , tType ) ;
2017-05-27 23:54:22 -04:00
java . append ( " return ret; \ n " ) ;
2017-05-17 17:32:48 -04:00
java . append ( " } \ n \ n public " ) . append ( kType ) . append ( " getFirstColumn(final java.sql.ResultSet rs, final java.util.Calendar cal) throws java.sql.SQLException { \ n " ) ;
if ( _mapKeyType ! = null ) {
java . append ( " return " ) ;
2017-05-27 23:54:22 -04:00
extractColumnValueString ( java , 1 , _mapKeyType ) ;
2017-05-17 17:32:48 -04:00
} else {
java . append ( " throw new com.moparisthebest.jdbc.MapperException(com.moparisthebest.jdbc.CompilingRowToObjectMapper.firstColumnError) " ) ;
}
2017-06-18 21:58:55 -04:00
if ( reflectionFieldIndex = = - 1 ) {
java . append ( footer ) ;
} else {
// otherwise we have a reflection field array to set up...
java . append ( " ; \ n } \ n \ n " ) ;
java . append ( " private static final java.lang.reflect.Field[] _fields = new java.lang.reflect.Field[]{ \ n " ) ;
for ( final AccessibleObject ao : _fields )
if ( ao instanceof ReflectionAccessibleObject ) {
final Field f = ( ( ReflectionAccessibleObject ) ao ) . field ;
java . append ( " com.moparisthebest.jdbc.util.ReflectionUtil.getAccessibleField( " )
. append ( f . getDeclaringClass ( ) . getCanonicalName ( ) ) . append ( " .class, \" " )
. append ( f . getName ( ) ) . append ( " \" ), \ n " ) ;
}
java . append ( " }; \ n} \ n " ) ;
}
2017-05-18 14:26:23 -04:00
//System.out.println(java);
2017-05-16 16:56:53 -04:00
return compiler . compile ( className , java ) ;
}
2017-05-27 23:54:22 -04:00
public void gen ( final Appendable java , final String tType ) throws IOException {
2017-05-16 16:56:53 -04:00
2017-05-17 17:32:48 -04:00
if ( mapOnlySecondColumn ) {
2017-05-27 23:54:22 -04:00
java . append ( " final " ) . append ( tType ) . append ( " ret = " ) ;
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , 2 , _returnTypeClass ) ;
2017-05-17 17:32:48 -04:00
java . append ( " ; \ n " ) ;
return ;
}
2017-06-19 21:08:22 -04:00
try {
lazyLoadConstructor ( ) ;
} catch ( SQLException e ) {
throw new MapperException ( e . getMessage ( ) , e ) ;
}
2017-05-17 13:07:08 -04:00
2017-05-16 16:56:53 -04:00
if ( resultSetConstructor ) {
2017-05-27 23:54:22 -04:00
java . append ( " final " ) . append ( tType ) . append ( " ret = new " ) . append ( tType ) . append ( " (rs); \ n " ) ;
2017-05-16 16:56:53 -04:00
return ;
}
2017-06-19 21:08:22 -04:00
if ( _fieldOrder ! = null ) {
java . append ( " final " ) . append ( tType ) . append ( " ret = new " ) . append ( tType ) . append ( " ( \ n " ) ;
for ( int x = 1 ; x < = _columnCount ; + + x ) {
extractColumnValueString ( java , _fieldOrder [ x ] , _fieldTypes [ x ] , _fieldClasses [ x ] = = null ? null : _fieldClasses [ x ] . getCanonicalName ( ) ) ;
if ( x ! = _columnCount )
java . append ( " , \ n " ) ;
//_args[x-1] = extractColumnValue(_fieldOrder[x], _fieldTypes[x], _fieldClasses[x]);
}
java . append ( " ); \ n " ) ;
return ;
}
2017-05-16 16:56:53 -04:00
if ( returnMap ) // we want a map
try {
2017-05-17 11:18:58 -04:00
java . append ( " final " ) . append ( tType ) . append ( " <String, Object> ret = new " ) . append ( tType ) . append ( " <String, Object>(); \ n " ) ;
2017-05-16 16:56:53 -04:00
final int columnLength = _columnCount + 1 ;
if ( componentType ! = null & & componentType ! = Object . class ) { // we want a specific value type
int typeId = _tmf . getTypeId ( componentType ) ;
2017-06-13 21:42:32 -04:00
final String enumName = componentType . getCanonicalName ( ) ;
2017-05-16 16:56:53 -04:00
for ( int x = 1 ; x < columnLength ; + + x ) {
2017-05-26 11:43:33 -04:00
java . append ( " ret.put( " ) . append ( escapeMapKeyString ( keys [ x ] ) . toLowerCase ( ) ) . append ( " , " ) ;
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , x , typeId , enumName ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ); \ n " ) ;
}
} else // we want a generic object type
for ( int x = 1 ; x < columnLength ; + + x )
2017-05-27 23:54:22 -04:00
java . append ( " ret.put( " ) . append ( escapeMapKeyString ( keys [ x ] . toLowerCase ( ) ) ) . append ( " , rs.getObject( " ) . append ( String . valueOf ( x ) ) . append ( " )); \ n " ) ;
2017-05-16 16:56:53 -04:00
return ;
} catch ( Throwable e ) {
throw new MapperException ( e . getClass ( ) . getName ( ) + " when trying to create a Map<String, "
+ ( componentType = = null ? " java.lang.Object " : componentType . getName ( ) ) + " > from a ResultSet row " +
" , all columns must be of the map value type " , e ) ;
}
else if ( componentType ! = null ) // we want an array
try {
2017-05-27 23:54:22 -04:00
java . append ( " final " ) . append ( tType ) . append ( " ret = new " ) . append ( tType . substring ( 0 , tType . length ( ) - 1 ) ) . append ( String . valueOf ( _columnCount ) ) . append ( " ]; \ n " ) ;
2017-05-16 16:56:53 -04:00
final int typeId = _tmf . getTypeId ( componentType ) ;
2017-06-13 21:42:32 -04:00
final String enumName = componentType . getCanonicalName ( ) ;
2017-05-16 16:56:53 -04:00
for ( int x = 0 ; x < _columnCount ; ) {
2017-05-27 23:54:22 -04:00
java . append ( " ret[ " ) . append ( String . valueOf ( x ) ) . append ( " ] = " ) ;
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , + + x , typeId , enumName ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ; \ n " ) ;
}
2017-05-17 11:18:58 -04:00
return ;
2017-05-16 16:56:53 -04:00
} catch ( Throwable e ) {
throw new MapperException ( e . getClass ( ) . getName ( ) + " when trying to create a "
+ componentType . getName ( ) + " [] from a ResultSet row, all columns must be of that type " , e ) ;
}
// if the ResultSet only contains a single column we may be able to map directly
// to the return type -- if so we don't need to build any structures to support
// mapping
if ( _columnCount = = 1 ) {
final int typeId = _tmf . getTypeId ( _returnTypeClass ) ;
try {
if ( typeId ! = TypeMappingsFactory . TYPE_UNKNOWN ) {
2017-05-27 23:54:22 -04:00
java . append ( " final " ) . append ( tType ) . append ( " ret = " ) ;
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , 1 , typeId , _returnTypeClass . getCanonicalName ( ) ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ; \ n " ) ;
return ;
} else {
// we still might want a single value (i.e. java.util.Date)
/ *
Object val = extractColumnValue ( 1 , typeId ) ;
if ( _returnTypeClass . isAssignableFrom ( val . getClass ( ) ) ) {
return _returnTypeClass . cast ( val ) ;
}
* /
// we could actually pull from first row like above and test it first and fail now, but maybe just failing during compilation is enough?
2017-05-27 23:54:22 -04:00
java . append ( " final " ) . append ( tType ) . append ( " ret = ( " ) . append ( tType ) . append ( " ) " ) ;
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , 1 , typeId , _returnTypeClass . getCanonicalName ( ) ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ; \ n " ) ;
return ;
}
} catch ( Exception e ) {
throw new MapperException ( e . getMessage ( ) , e ) ;
}
}
if ( _fields = = null ) {
try {
super . getFieldMappings ( ) ;
} catch ( SQLException e ) {
throw new MapperException ( e . getMessage ( ) , e ) ;
}
}
java . append ( " final " ) . append ( tType ) . append ( " ret = new " ) . append ( tType ) . append ( " (); \ n " ) ;
for ( int i = 1 ; i < _fields . length ; i + + ) {
AccessibleObject f = _fields [ i ] ;
if ( f instanceof Field ) {
// if f not accessible (but super.getFieldMappings() sets it), throw exception during compilation is fine
java . append ( " ret. " ) . append ( ( ( Field ) f ) . getName ( ) ) . append ( " = " ) ;
2017-06-18 21:58:55 -04:00
extractColumnValueString ( java , i , _fieldTypes [ i ] ,
2017-06-19 21:08:22 -04:00
_fieldClasses [ i ] = = null ? null : _fieldClasses [ i ] . getCanonicalName ( ) ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ; \ n " ) ;
2017-06-18 21:58:55 -04:00
} else if ( f instanceof ReflectionAccessibleObject ) {
java . append ( " com.moparisthebest.jdbc.util.ReflectionUtil.setValue(_fields[ " ) . append ( String . valueOf ( ( ( ReflectionAccessibleObject ) f ) . index ) ) . append ( " ], ret, " ) ;
extractColumnValueString ( java , i , _fieldTypes [ i ] ,
2017-06-19 21:08:22 -04:00
_fieldClasses [ i ] = = null ? null : _fieldClasses [ i ] . getCanonicalName ( ) ) ;
2017-06-18 21:58:55 -04:00
java . append ( " ); \ n " ) ;
2017-05-16 16:56:53 -04:00
} else {
java . append ( " ret. " ) . append ( ( ( Method ) f ) . getName ( ) ) . append ( " ( " ) ;
2017-06-18 21:58:55 -04:00
extractColumnValueString ( java , i , _fieldTypes [ i ] ,
2017-06-19 21:08:22 -04:00
_fieldClasses [ i ] = = null ? null : _fieldClasses [ i ] . getCanonicalName ( ) ) ;
2017-05-16 16:56:53 -04:00
java . append ( " ); \ n " ) ;
}
}
// if this resultObject is Finishable, call finish()
if ( Finishable . class . isAssignableFrom ( _returnTypeClass ) )
java . append ( " ret.finish(rs); \ n " ) ;
2017-05-27 23:54:22 -04:00
}
2017-06-18 21:58:55 -04:00
@Override
protected AccessibleObject modField ( final Field field , final int index ) {
if ( ! allowReflection )
return field ;
final int modifiers = field . getModifiers ( ) ;
if ( Modifier . isFinal ( modifiers ) | | Modifier . isPrivate ( modifiers ) | | Modifier . isProtected ( modifiers ) ) {
return new ReflectionAccessibleObject ( field , + + reflectionFieldIndex ) ;
}
return field ;
}
2017-06-13 21:42:32 -04:00
public void extractColumnValueString ( final Appendable java , final int index , final int resultType , final String enumName ) throws IOException {
extractColumnValueString ( java , index , resultType , enumName , _calendarName ) ;
2017-06-07 20:30:58 -04:00
}
public void extractColumnValueString ( final Appendable java , final int index , final Class resultType ) throws IOException {
extractColumnValueString ( java , index , resultType , _calendarName ) ;
}
public static class ResultSetKey extends CachingRowToObjectMapper . ResultSetKey {
protected final boolean hasCalendar ;
public ResultSetKey ( final String [ ] keys , final Class < ? > returnTypeClass , final Class < ? > mapKeyType , final boolean hasCalendar ) {
super ( keys , returnTypeClass , mapKeyType ) ;
this . hasCalendar = hasCalendar ;
}
@Override
public boolean equals ( final Object o ) {
if ( this = = o ) return true ;
if ( ! ( o instanceof ResultSetKey ) ) return false ;
final ResultSetKey that = ( ResultSetKey ) o ;
return hasCalendar = = that . hasCalendar & & super . equals ( o ) ;
}
@Override
public int hashCode ( ) {
int result = super . hashCode ( ) ;
result = 31 * result + ( hasCalendar ? 1 : 0 ) ;
return result ;
}
}
2017-05-27 23:54:22 -04:00
2017-06-07 20:30:58 -04:00
public static void extractColumnValueString ( final Appendable java , final int index , final Class resultType , final String calendarName ) throws IOException {
2017-06-13 21:42:32 -04:00
extractColumnValueString ( java , index , _tmf . getTypeId ( resultType ) , resultType . getCanonicalName ( ) , " rs " , calendarName ) ;
2017-06-12 19:24:04 -04:00
}
2017-06-13 21:42:32 -04:00
public static void extractColumnValueString ( final Appendable java , final int index , final int resultType , final String enumName , final String calendarName ) throws IOException {
extractColumnValueString ( java , index , resultType , enumName , " rs " , calendarName ) ;
2017-05-16 16:56:53 -04:00
}
/ * *
* Extract a column value from the ResultSet and return it as resultType .
*
* @param index The column index of the value to extract from the ResultSet .
* @param resultType The return type . Defined in TypeMappingsFactory .
* @return The extracted value
* @throws java . sql . SQLException on error .
* /
2017-06-13 21:42:32 -04:00
public static void extractColumnValueString ( final Appendable java , final int index , final int resultType , final String enumName , final String resultSetName , final String calendarName ) throws IOException {
2017-05-16 16:56:53 -04:00
switch ( resultType ) {
case TypeMappingsFactory . TYPE_INT :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getInt( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_LONG :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getLong( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_FLOAT :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getFloat( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_DOUBLE :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getDouble( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BYTE :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getByte( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_SHORT :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getInt( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BOOLEAN :
2017-06-12 19:24:04 -04:00
java . append ( " getBooleanYN( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_INT_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectInt( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_LONG_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectLong( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_FLOAT_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectFloat( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_DOUBLE_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectDouble( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BYTE_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectByte( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_SHORT_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectShort( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BOOLEAN_OBJ :
2017-06-12 19:24:04 -04:00
java . append ( " getObjectBooleanYN( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_STRING :
case TypeMappingsFactory . TYPE_XMLBEAN_ENUM :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getString( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
2017-06-13 21:42:32 -04:00
case TypeMappingsFactory . TYPE_ENUM :
java . append ( enumName ) . append ( " .valueOf( " ) . append ( resultSetName ) . append ( " .getString( " ) . append ( String . valueOf ( index ) ) . append ( " )) " ) ;
return ;
2017-05-16 16:56:53 -04:00
case TypeMappingsFactory . TYPE_BIG_DECIMAL :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getBigDecimal( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BYTES :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getBytes( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_TIMESTAMP :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getTimestamp( " ) . append ( String . valueOf ( index ) ) ;
2017-06-07 20:30:58 -04:00
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_TIME :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getTime( " ) . append ( String . valueOf ( index ) ) ;
2017-06-07 20:30:58 -04:00
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_SQLDATE :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getDate( " ) . append ( String . valueOf ( index ) ) ;
2017-06-07 20:30:58 -04:00
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_DATE :
2017-06-12 19:24:04 -04:00
java . append ( " getUtilDate( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
2017-06-07 20:30:58 -04:00
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_CALENDAR :
2017-06-12 19:24:04 -04:00
java . append ( " getCalendar( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
2017-06-07 20:30:58 -04:00
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_REF :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getRef( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_BLOB :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getBlob( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_CLOB :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getClob( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_ARRAY :
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getArray( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
case TypeMappingsFactory . TYPE_READER :
case TypeMappingsFactory . TYPE_STREAM :
throw new MapperException ( " streaming return types are not supported by the JdbcControl; use ResultSet instead " ) ;
2017-06-13 22:56:00 -04:00
// start java.time support
case TypeMappingsFactory . TYPE_INSTANT :
java . append ( " getInstant( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_LOCALDATETIME :
java . append ( " getLocalDateTime( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_LOCALDATE :
java . append ( " getLocalDate( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_LOCALTIME :
java . append ( " getLocalTime( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
// todo: send in ZoneId here?
case TypeMappingsFactory . TYPE_ZONEDDATETIME :
java . append ( " getZonedDateTime( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_OFFSETDATETIME :
java . append ( " getOffsetDateTime( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_OFFSETTIME :
java . append ( " getOffsetTime( " ) . append ( resultSetName ) . append ( " , " ) . append ( String . valueOf ( index ) ) ;
if ( calendarName ! = null )
java . append ( " , " ) . append ( calendarName ) ;
java . append ( " ) " ) ;
return ;
case TypeMappingsFactory . TYPE_YEAR :
java . append ( " java.time.Year.parse( " ) . append ( resultSetName ) . append ( " .getString( " ) . append ( String . valueOf ( index ) ) . append ( " )) " ) ;
return ;
case TypeMappingsFactory . TYPE_ZONEID :
java . append ( " java.time.ZoneId.of( " ) . append ( resultSetName ) . append ( " .getString( " ) . append ( String . valueOf ( index ) ) . append ( " )) " ) ;
return ;
case TypeMappingsFactory . TYPE_ZONEOFFSET :
java . append ( " java.time.ZoneOffset.of( " ) . append ( resultSetName ) . append ( " .getString( " ) . append ( String . valueOf ( index ) ) . append ( " )) " ) ;
return ;
// end java.time support
2017-05-16 16:56:53 -04:00
case TypeMappingsFactory . TYPE_STRUCT :
case TypeMappingsFactory . TYPE_UNKNOWN :
// JAVA_TYPE (could be any), or REF
2017-06-12 19:24:04 -04:00
java . append ( resultSetName ) . append ( " .getObject( " ) . append ( String . valueOf ( index ) ) . append ( " ) " ) ;
2017-05-16 16:56:53 -04:00
return ;
default :
throw new MapperException ( " internal error: unknown type ID: " + Integer . toString ( resultType ) ) ;
}
}
}