Fork beehive-jdbc-mapper to com.moparisthebest.jdbcmapper:querymapper
This commit is contained in:
parent
d8f7e6df4a
commit
c245f2173a
@ -34,9 +34,8 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.moparisthebest.beehive</groupId>
|
||||
<artifactId>beehive-jdbc-mapper</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<groupId>com.moparisthebest.jdbcmapper</groupId>
|
||||
<artifactId>querymapper</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.moparisthebest.aptIn16</groupId>
|
||||
|
@ -1,133 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
function prepareFile(){
|
||||
path="$1"
|
||||
tmp_path="$(basename "$path")"
|
||||
(
|
||||
sed -n '/CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh/q;p' "$path"
|
||||
echo -e '\t// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh\n'
|
||||
) > "$tmp_path"
|
||||
echo "$tmp_path"
|
||||
}
|
||||
|
||||
function finishFile(){
|
||||
path="$1"
|
||||
tmp_path="$(basename "$path")"
|
||||
echo -e "}\n" >> "$tmp_path"
|
||||
mv "$tmp_path" "$path"
|
||||
}
|
||||
|
||||
|
||||
result="$(prepareFile "src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java")"
|
||||
|
||||
# single object types
|
||||
cat src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java | grep public | egrep '(toObject|toSingleMap)\(' | grep ', Calendar cal)' | while read method
|
||||
do
|
||||
#echo "method: $method"
|
||||
method_name=$(echo $method | egrep -o '[^ ]+\(')
|
||||
echo "ResultSetMapper.$method_name)"
|
||||
|
||||
cat >> "$result" <<EOF
|
||||
$(echo $method | sed "s/, Calendar cal)/)/")
|
||||
return this.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/rs/' -e 's/) {/);/')
|
||||
}
|
||||
|
||||
EOF
|
||||
done
|
||||
|
||||
#everything else
|
||||
cat src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java | grep public | grep '(ResultSet rs' | grep ', int arrayMaxLength, Calendar cal)' | while read method
|
||||
do
|
||||
#echo "method: $method"
|
||||
method_name=$(echo $method | egrep -o '[^ ]+\(')
|
||||
echo "ResultSetMapper.$method_name)"
|
||||
|
||||
for args in '' ', int arrayMaxLength' ', Calendar cal'
|
||||
do
|
||||
cat >> "$result" <<EOF
|
||||
$(echo $method | sed "s/, int arrayMaxLength, Calendar cal)/$args)/")
|
||||
return this.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/rs/' -e 's/) {/);/')
|
||||
}
|
||||
|
||||
EOF
|
||||
done
|
||||
done
|
||||
|
||||
finishFile "src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java"
|
||||
|
||||
query="$(prepareFile "src/main/java/com/moparisthebest/jdbc/QueryMapper.java")"
|
||||
caching_query="$(prepareFile "src/main/java/com/moparisthebest/jdbc/CachingQueryMapper.java")"
|
||||
null_query="$(prepareFile "src/main/java/com/moparisthebest/jdbc/NullQueryMapper.java")"
|
||||
list_query="$(prepareFile "src/main/java/com/moparisthebest/jdbc/ListQueryMapper.java")"
|
||||
|
||||
cat src/main/java/com/moparisthebest/jdbc/ResultSetMapper.java | grep public | grep '(ResultSet rs' | egrep -v '(int arrayMaxLength|Calendar cal)' | while read method
|
||||
do
|
||||
#echo "method: $method"
|
||||
method_name=$(echo $method | egrep -o '[^ ]+\(')
|
||||
echo "QueryMapper.$method_name)"
|
||||
|
||||
# QueryMapper.java
|
||||
cat >> "$query" <<EOF
|
||||
$(echo $method | sed -e 's/ResultSet rs/PreparedStatement ps/' -e 's/) {/, final Object... bindObjects) throws SQLException {/')
|
||||
return cm.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/bindExecute(ps, bindObjects)/' -e 's/) {/);/')
|
||||
}
|
||||
|
||||
$(echo $method | sed -e 's/ResultSet rs/String sql/' -e 's/) {/, final Object... bindObjects) throws SQLException {/')
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/ps/' -e 's/) {/, bindObjects);/')
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
# CachingQueryMapper.java
|
||||
cat >> "$caching_query" <<EOF
|
||||
@Override
|
||||
$(echo $method | sed -e 's/ResultSet rs/String sql/' -e 's/) {/, final Object... bindObjects) throws SQLException {/')
|
||||
return super.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/getPreparedStatement(sql)/' -e 's/) {/, bindObjects);/')
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
# NullQueryMapper.java
|
||||
for type in PreparedStatement String
|
||||
do
|
||||
cat <<EOF
|
||||
@Override
|
||||
$(echo $method | sed -e "s/ResultSet rs/$type query/" -e 's/) {/, final Object... bindObjects) {/')
|
||||
try {
|
||||
return delegate.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/query/' -e 's/) {/, bindObjects);/')
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
EOF
|
||||
done >> "$null_query"
|
||||
|
||||
# ListQueryMapper.java
|
||||
cat >> "$list_query" <<EOF
|
||||
@Override
|
||||
$(echo $method | sed -e 's/ResultSet rs/PreparedStatement ps/' -e 's/) {/, final Object... bindObjects) throws SQLException {/')
|
||||
return delegate.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/ps/' -e 's/) {/, bindObjects);/')
|
||||
}
|
||||
|
||||
@Override
|
||||
$(echo $method | sed -e 's/ResultSet rs/String sql/' -e 's/) {/, final Object... bindObjects) throws SQLException {/')
|
||||
return delegate.$method_name$(echo $method | sed -e 's/^.*(//' -e 's/final //g' -e 's/, [^ ]* /, /g' -e 's/ResultSet rs/prepareSql(sql, bindObjects)/' -e 's/) {/, bindObjects);/')
|
||||
}
|
||||
|
||||
EOF
|
||||
done
|
||||
|
||||
finishFile "src/main/java/com/moparisthebest/jdbc/QueryMapper.java"
|
||||
finishFile "src/main/java/com/moparisthebest/jdbc/CachingQueryMapper.java"
|
||||
finishFile "src/main/java/com/moparisthebest/jdbc/NullQueryMapper.java"
|
||||
finishFile "src/main/java/com/moparisthebest/jdbc/ListQueryMapper.java"
|
@ -14,45 +14,11 @@
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
<groupId>com.moparisthebest.jdbcmapper</groupId>
|
||||
<artifactId>querymapper</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<debug>true</debug>
|
||||
<!--compilerArgument>-Xlint:unchecked</compilerArgument-->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>my-testCompile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<annotationProcessors>
|
||||
<annotationProcessor>com.moparisthebest.jdbc.codegen.JdbcMapperProcessor</annotationProcessor>
|
||||
</annotationProcessors>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -1,26 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/25/17.
|
||||
*/
|
||||
public abstract class AbstractSQLParser implements SQLParser {
|
||||
|
||||
private final String[] columnNames;
|
||||
private final boolean isSelect;
|
||||
|
||||
protected AbstractSQLParser(final String[] columnNames, final boolean isSelect) {
|
||||
this.columnNames = columnNames;
|
||||
this.isSelect = isSelect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String[] columnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSelect() {
|
||||
return isSelect;
|
||||
}
|
||||
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This let's you take compile and then run Java source code at runtime, this class only allows you to compile 1 class
|
||||
* at a time.
|
||||
* <p>
|
||||
* This is not thread safe, though it could be extended and made thread safe, or locked around.
|
||||
*
|
||||
* @author moparisthebest
|
||||
* @see MultiCompiler for compiling multiple classes at once
|
||||
* <p>
|
||||
* The original idea was taken from:
|
||||
* http://mindprod.com/jgloss/javacompiler.html#SAMPLECODE
|
||||
*/
|
||||
public class Compiler {
|
||||
|
||||
private final JavaCompiler compiler;
|
||||
private final MemoryJavaFileManager mjfm;
|
||||
//private final ClassLoader classLoader;
|
||||
private final List<JavaFileObject> singleton = Arrays.asList(new JavaFileObject[1]);
|
||||
|
||||
public Compiler() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
protected Compiler(final boolean multi) {
|
||||
compiler = ToolProvider.getSystemJavaCompiler();
|
||||
if (compiler == null)
|
||||
throw new RuntimeException("tools.jar needs to be on classpath to compile code at runtime");
|
||||
final JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
|
||||
mjfm = multi ? new MultiMemoryJavaFileManager(fileManager) : new SingleMemoryJavaFileManager(fileManager);
|
||||
//classLoader = new MemoryClassLoader(mjfm);
|
||||
}
|
||||
|
||||
protected ClassLoader compile(final Iterable<? extends JavaFileObject> source) {
|
||||
//final MemoryJavaFileManager mjfm = new MemoryJavaFileManager(compiler.getStandardFileManager(null, null, null));
|
||||
final JavaCompiler.CompilationTask task = compiler.getTask(null, mjfm, null, null, null, source);
|
||||
return task.call() ?
|
||||
new MemoryClassLoader(mjfm)
|
||||
//classLoader
|
||||
: null;
|
||||
}
|
||||
|
||||
protected ClassLoader compile(final JavaFileObject... source) {
|
||||
return compile(Arrays.asList(source));
|
||||
}
|
||||
|
||||
public ClassLoader compile(final JavaFileObject source) {
|
||||
singleton.set(0, source);
|
||||
return compile(singleton);
|
||||
}
|
||||
|
||||
protected <T> T compile(final String className, final Iterable<? extends JavaFileObject> source) {
|
||||
// compile item
|
||||
final ClassLoader cl = compile(source);
|
||||
if (cl == null)
|
||||
throw new RuntimeException("Error compiling class, aborting...");
|
||||
return instantiate(cl, className);
|
||||
}
|
||||
|
||||
protected <T> T compile(final String className, final JavaFileObject... source) {
|
||||
return compile(className, Arrays.asList(source));
|
||||
}
|
||||
|
||||
public <T> T compile(final String className, final JavaFileObject source) {
|
||||
singleton.set(0, source);
|
||||
return compile(className, singleton);
|
||||
}
|
||||
|
||||
public <T> T compile(final String className, final CharSequence code) {
|
||||
return compile(className, new StringJavaFileObject(className, code));
|
||||
}
|
||||
|
||||
public <T> T instantiate(final ClassLoader cl, final String className) {
|
||||
try {
|
||||
// Load class and create an instance.
|
||||
final Class<?> calcClass = cl.loadClass(className);
|
||||
@SuppressWarnings("unchecked") final T ret = (T) calcClass.newInstance();
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error finding or instantiating class, exiting...", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MemoryJavaFileObject extends ForwardingJavaFileObject<JavaFileObject> {
|
||||
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
MemoryJavaFileObject(JavaFileObject fileObject) {
|
||||
super(fileObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return baos;
|
||||
}
|
||||
}
|
||||
|
||||
interface MemoryJavaFileManager extends JavaFileManager {
|
||||
MemoryJavaFileObject getMemoryJavaFileObject(final String name);
|
||||
}
|
||||
|
||||
class SingleMemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> implements MemoryJavaFileManager {
|
||||
|
||||
private MemoryJavaFileObject classes = null;
|
||||
|
||||
SingleMemoryJavaFileManager(JavaFileManager fileManager) {
|
||||
super(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryJavaFileObject getMemoryJavaFileObject(final String name) {
|
||||
final MemoryJavaFileObject ret = classes;
|
||||
classes = null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
|
||||
final MemoryJavaFileObject jfo = new MemoryJavaFileObject(super.getJavaFileForOutput(location, className, kind, sibling));
|
||||
//System.out.printf("MemoryJavaFileManager.getJavaFileForOutput(%s, %s, %s, %s): %s\n", location, className, kind, sibling, jfo);
|
||||
classes = jfo;
|
||||
return jfo;
|
||||
}
|
||||
}
|
||||
|
||||
class MultiMemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> implements MemoryJavaFileManager {
|
||||
|
||||
private Map<String, MemoryJavaFileObject> classes = new HashMap<String, MemoryJavaFileObject>();
|
||||
|
||||
MultiMemoryJavaFileManager(JavaFileManager fileManager) {
|
||||
super(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryJavaFileObject getMemoryJavaFileObject(final String name) {
|
||||
return classes.remove(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
|
||||
final MemoryJavaFileObject jfo = new MemoryJavaFileObject(super.getJavaFileForOutput(location, className, kind, sibling));
|
||||
//System.out.printf("MemoryJavaFileManager.getJavaFileForOutput(%s, %s, %s, %s): %s\n", location, className, kind, sibling, jfo);
|
||||
classes.put(className, jfo);
|
||||
return jfo;
|
||||
}
|
||||
}
|
||||
|
||||
class MemoryClassLoader extends ClassLoader {
|
||||
final MemoryJavaFileManager jfm;
|
||||
|
||||
MemoryClassLoader(MemoryJavaFileManager jfm) {
|
||||
this.jfm = jfm;
|
||||
}
|
||||
|
||||
public Class findClass(String name) throws ClassNotFoundException {
|
||||
final MemoryJavaFileObject jfo = jfm.getMemoryJavaFileObject(name);
|
||||
if (jfo == null)
|
||||
throw new ClassNotFoundException("Class '" + name + "' cannot be found in the MemoryJavaFileManager");
|
||||
final byte[] b = jfo.baos.toByteArray();
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
/**
|
||||
* This lets you compile multiple source files at once
|
||||
*/
|
||||
public class MultiCompiler extends Compiler {
|
||||
|
||||
public static Compiler instance = new MultiCompiler();
|
||||
|
||||
public MultiCompiler() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader compile(final Iterable<? extends JavaFileObject> source) {
|
||||
return super.compile(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader compile(final JavaFileObject... source) {
|
||||
return super.compile(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T compile(final String className, final JavaFileObject... source) {
|
||||
return super.compile(className, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T compile(final String className, final Iterable<? extends JavaFileObject> source) {
|
||||
return super.compile(className, source);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/25/17.
|
||||
*/
|
||||
public interface SQLParser {
|
||||
|
||||
/**
|
||||
* Return SQLParser instance for given SQL
|
||||
*
|
||||
* @param sql SQL to parse
|
||||
* @return instance with string parsed
|
||||
*/
|
||||
SQLParser parse(String sql);
|
||||
|
||||
/**
|
||||
* @return column names for select, with 1-based index like ResultSet, index 0 is always null, not used if isSelect() returns false
|
||||
*/
|
||||
String[] columnNames();
|
||||
|
||||
/**
|
||||
* Return
|
||||
*
|
||||
* @return true for Select, if we will map to an object, false to call executeUpdate (insert/update/merge/?)
|
||||
*/
|
||||
boolean isSelect();
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/25/17.
|
||||
*/
|
||||
public class SimpleSQLParser extends AbstractSQLParser {
|
||||
|
||||
private static final Pattern aliasPattern = Pattern.compile("^.*\\.");
|
||||
|
||||
public SimpleSQLParser() {
|
||||
super(null, false);
|
||||
}
|
||||
|
||||
|
||||
private SimpleSQLParser(final String[] columnNames, final boolean isSelect) {
|
||||
super(columnNames, isSelect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLParser parse(String sql) {
|
||||
sql = sql.toUpperCase();
|
||||
final boolean isSelect = sql.startsWith("SELECT");
|
||||
String[] columnNames = null;
|
||||
if (isSelect) {
|
||||
final String columns = sql.substring(sql.indexOf("SELECT") + 6, sql.indexOf("FROM")).trim();
|
||||
final String[] splitColumns = columns.split(",");
|
||||
columnNames = new String[splitColumns.length + 1];
|
||||
int index = 0;
|
||||
for (String column : splitColumns) {
|
||||
final String[] singleSplit = column.split("\\s");
|
||||
// trim and remove leading table/alias
|
||||
columnNames[++index] = aliasPattern.matcher(singleSplit[singleSplit.length - 1].trim()).replaceFirst("");
|
||||
}
|
||||
}
|
||||
return new SimpleSQLParser(columnNames, isSelect);
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.moparisthebest.classgen;
|
||||
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* For sending java source as strings to a Compiler
|
||||
* @see Compiler
|
||||
*/
|
||||
public class StringJavaFileObject extends SimpleJavaFileObject {
|
||||
private final CharSequence code;
|
||||
|
||||
public StringJavaFileObject(final String name, final CharSequence code) {
|
||||
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return code;
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Abstract base class for all row mappers.
|
||||
*
|
||||
* RowMappers are used to map the contents of a row in a ResultSet to the return type of an annotated method.
|
||||
* Supported RowMapper types include: HashMap, Map, Object, XmlObject. When a ResultSetMapper is ready to
|
||||
* map a ResultSet row to an object, it requests a RowMapper for the return type of the method from the
|
||||
* RowMapperFactory.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractRowMapper<K, T> implements RowMapper<K,T> {
|
||||
|
||||
/** ResultSet to map. */
|
||||
protected final ResultSet _resultSet;
|
||||
|
||||
/** Calendar instance for date/time mappings. */
|
||||
protected final Calendar _cal;
|
||||
|
||||
/** Class to map ResultSet Rows to. */
|
||||
protected final Class<T> _returnTypeClass;
|
||||
|
||||
protected final Class<K> _mapKeyType;
|
||||
|
||||
protected final int _columnCount;
|
||||
|
||||
protected final boolean mapOnlySecondColumn;
|
||||
|
||||
protected String[] keys = null; // for caching if we must generate class
|
||||
|
||||
/**
|
||||
* Create a new RowMapper for the specified ResultSet and return type Class.
|
||||
* @param resultSet ResultSet to map
|
||||
* @param returnTypeClass Class to map ResultSet rows to.
|
||||
* @param cal Calendar instance for date/time values.
|
||||
*/
|
||||
protected AbstractRowMapper(String[] keys, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<K> mapKeyType) {
|
||||
_resultSet = resultSet;
|
||||
_returnTypeClass = returnTypeClass;
|
||||
_cal = cal;
|
||||
_mapKeyType = mapKeyType;
|
||||
|
||||
if(keys == null) {
|
||||
try {
|
||||
_columnCount = resultSet.getMetaData().getColumnCount();
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
this.keys = keys;
|
||||
_columnCount = keys.length - 1;
|
||||
}
|
||||
|
||||
mapOnlySecondColumn = _mapKeyType != null && _columnCount == 2;
|
||||
}
|
||||
|
||||
protected AbstractRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<K> mapKeyType) {
|
||||
this(null, resultSet, returnTypeClass, cal, mapKeyType);
|
||||
}
|
||||
|
||||
protected AbstractRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal) {
|
||||
this(resultSet, returnTypeClass, cal, null);
|
||||
}
|
||||
|
||||
protected AbstractRowMapper(String[] keys, Class<T> returnTypeClass, Calendar cal, Class<K> mapKeyType) {
|
||||
this(keys, null, returnTypeClass, cal, mapKeyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a String array of column names from the ResultSet.
|
||||
* @return A String array containing the column names contained within the ResultSet.
|
||||
* @throws java.sql.SQLException on error
|
||||
*/
|
||||
protected String[] getKeysFromResultSet() throws SQLException {
|
||||
|
||||
if(this.keys != null)
|
||||
return this.keys;
|
||||
|
||||
String[] keys;
|
||||
final ResultSetMetaData md = _resultSet.getMetaData();
|
||||
|
||||
keys = new String[_columnCount + 1];
|
||||
for (int i = 1; i <= _columnCount; i++) {
|
||||
//keys[i] = md.getColumnName(i).toUpperCase();
|
||||
keys[i] = md.getColumnLabel(i).toUpperCase();
|
||||
}
|
||||
return this.keys = keys;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by mopar on 4/29/15.
|
||||
*/
|
||||
public class ArrayInList implements InList {
|
||||
|
||||
private static final InList instance = new ArrayInList();
|
||||
|
||||
public static InList instance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ArrayInList() {
|
||||
}
|
||||
|
||||
protected String columnAppend(final String columnName) {
|
||||
return "(" + columnName + " = ANY(?))";
|
||||
}
|
||||
|
||||
protected <T> Array toArray(final Connection conn, final Collection<T> values) throws SQLException {
|
||||
return conn.createArrayOf(
|
||||
values.iterator().next() instanceof Number ? "number" : "text",
|
||||
values.toArray()
|
||||
);
|
||||
}
|
||||
|
||||
public <T> InListObject inList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException {
|
||||
return values == null || values.isEmpty() ? InListObject.empty : new ArrayListObject(
|
||||
columnAppend(columnName),
|
||||
toArray(conn, values)
|
||||
);
|
||||
}
|
||||
|
||||
class ArrayListObject extends InListObject {
|
||||
private final Array array;
|
||||
|
||||
public ArrayListObject(final String sql, final Array array) {
|
||||
super(sql);
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public Array getArray() {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by mopar on 4/29/15.
|
||||
*/
|
||||
public class BindInList implements InList {
|
||||
|
||||
private static final int defaultMaxSize = Integer.parseInt(System.getProperty("QueryMapper.BindInList.defaultMaxSize", "999"));
|
||||
|
||||
private static final InList instance = new BindInList();
|
||||
|
||||
public static InList instance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private final int maxSize;
|
||||
|
||||
public BindInList(final int maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
protected BindInList() {
|
||||
this(defaultMaxSize);
|
||||
}
|
||||
|
||||
private static <T> List<List<T>> split(final List<T> list, final int maxLength) {
|
||||
final int listSize = list.size();
|
||||
final List<List<T>> ret = new ArrayList<List<T>>();
|
||||
if (listSize < maxLength)
|
||||
ret.add(list);
|
||||
else
|
||||
for (int fromIndex = 0, toIndex = maxLength; fromIndex < listSize; fromIndex = toIndex, toIndex += maxLength)
|
||||
ret.add(list.subList(fromIndex, toIndex > listSize ? listSize : toIndex));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private <T> String toInList(final String fieldName, final Collection<T> items) {
|
||||
final StringBuilder sb = new StringBuilder("(");
|
||||
|
||||
// do it quick if it will fit in one in-list
|
||||
if (items.size() < maxSize) // 999 or less
|
||||
return buildInList(items, sb, fieldName).append(")").toString();
|
||||
|
||||
// else we need to split lists
|
||||
boolean notFirst = false;
|
||||
for (final List<T> item : split(new ArrayList<T>(items), maxSize)) {
|
||||
if (notFirst) sb.append(" OR ");
|
||||
else notFirst = true;
|
||||
buildInList(item, sb, fieldName);
|
||||
}
|
||||
|
||||
return sb.append(")").toString();
|
||||
}
|
||||
|
||||
private static <T> StringBuilder buildInList(Iterable<T> list, StringBuilder sb, String fieldName) {
|
||||
return oracleCommaSeparatedList(list, sb.append(fieldName).append(" IN (")).append(")");
|
||||
}
|
||||
|
||||
private static <T> StringBuilder oracleCommaSeparatedList(Iterable<T> list, StringBuilder sb) {
|
||||
boolean notFirst = false;
|
||||
for (final T obj : list) {
|
||||
// DO NOT DO THIS ANYMORE: if (obj == null) continue;
|
||||
if (notFirst) sb.append(',');
|
||||
else notFirst = true;
|
||||
sb.append('?');
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public <T> InListObject inList(final Connection conn, final String columnName, final Collection<T> values) {
|
||||
return values == null || values.isEmpty() ? InListObject.empty : new BindInListObject(
|
||||
toInList(columnName, values),
|
||||
values.toArray()
|
||||
);
|
||||
}
|
||||
|
||||
class BindInListObject extends InListObject {
|
||||
private final Object[] bindObjects;
|
||||
|
||||
public BindInListObject(final String sql, final Object[] bindObjects) {
|
||||
super(sql);
|
||||
this.bindObjects = bindObjects;
|
||||
}
|
||||
|
||||
public Object[] getBindObjects() {
|
||||
return bindObjects;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,291 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
|
||||
/**
|
||||
* This class caches the PreparedStatement's it creates for the strings you send in, then closes them when the close() method is called.
|
||||
* Since PreparedStatement is not thread-safe, this class cannot be either. Be sure to call it from only a single thread
|
||||
* or synchronize around it.
|
||||
*/
|
||||
public class CachingQueryMapper extends QueryMapper {
|
||||
|
||||
protected final Map<String, PreparedStatement> cache;
|
||||
|
||||
protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm, final int maxEntries) {
|
||||
super(conn, jndiName, cm);
|
||||
if (maxEntries > 0) { // we want a limited cache
|
||||
final float loadFactor = 0.75f; // default for HashMaps
|
||||
// if we set the initialCapacity this way, nothing should ever need re-sized
|
||||
final int initialCapacity = ((int) Math.ceil(maxEntries / loadFactor)) + 1;
|
||||
cache = new LinkedHashMap<String, PreparedStatement>(initialCapacity, loadFactor, true) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<String, PreparedStatement> eldest) {
|
||||
final boolean remove = size() > maxEntries;
|
||||
if(remove){
|
||||
//System.out.printf("closing PreparedStatement '%s' with key '%s'\n", eldest.getValue(), eldest.getKey());
|
||||
tryClose(eldest.getValue());
|
||||
}
|
||||
return remove;
|
||||
}
|
||||
};
|
||||
} else
|
||||
cache = new HashMap<String, PreparedStatement>();
|
||||
}
|
||||
|
||||
public CachingQueryMapper(Connection conn, ResultSetMapper cm, final int maxEntries) {
|
||||
this(conn, null, cm, maxEntries);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(Connection conn, final int maxEntries) {
|
||||
this(conn, null, null, maxEntries);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(String jndiName, ResultSetMapper cm, final int maxEntries) {
|
||||
this(null, jndiName, cm, maxEntries);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(String jndiName, final int maxEntries) {
|
||||
this(null, jndiName, null, maxEntries);
|
||||
}
|
||||
|
||||
protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm) {
|
||||
this(conn, jndiName, cm, 20); // default size of 20
|
||||
}
|
||||
|
||||
public CachingQueryMapper(Connection conn, ResultSetMapper cm) {
|
||||
this(conn, null, cm);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(Connection conn) {
|
||||
this(conn, null, null);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(String jndiName, ResultSetMapper cm) {
|
||||
this(null, jndiName, cm);
|
||||
}
|
||||
|
||||
public CachingQueryMapper(String jndiName) {
|
||||
this(null, jndiName, null);
|
||||
}
|
||||
|
||||
protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
|
||||
return getPreparedStatement(sql, ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
|
||||
}
|
||||
|
||||
protected PreparedStatement getPreparedStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
PreparedStatement ps = cache.get(sql);
|
||||
if (ps == null) {
|
||||
//System.out.println("cache miss");
|
||||
ps = conn.prepareStatement(sql,resultSetType,resultSetConcurrency);
|
||||
cache.put(sql, ps);
|
||||
}
|
||||
//else System.out.println("cache hit");
|
||||
return ps;
|
||||
}
|
||||
|
||||
public void clearCache(boolean close) {
|
||||
//System.out.println("cache size: "+cache.size());
|
||||
for (PreparedStatement ps : cache.values())
|
||||
tryClose(ps);
|
||||
if (close)
|
||||
super.close();
|
||||
else
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
this.clearCache(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.clearCache(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, Object... bindObjects) throws SQLException {
|
||||
return super.executeUpdate(getPreparedStatement(sql), bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUpdateSuccess(String sql, Object... bindObjects) throws SQLException {
|
||||
return super.executeUpdateSuccess(getPreparedStatement(sql), bindObjects);
|
||||
}
|
||||
|
||||
// these grab ResultSets from the database
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(String sql, Object... bindObjects) throws SQLException {
|
||||
return super.toResultSet(getPreparedStatement(sql), bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(String sql, Integer rsType, Integer rsConcurrency, Object... bindObjects) throws SQLException {
|
||||
return super.toResultSet(getPreparedStatement(sql,rsType,rsConcurrency), bindObjects);
|
||||
}
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||
|
||||
@Override
|
||||
public <T> T toObject(String sql, Class<T> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toObject(getPreparedStatement(sql), componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(String sql, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toSingleMap(getPreparedStatement(sql), componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Map<String, V> toSingleMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toSingleMap(getPreparedStatement(sql), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toCollection(getPreparedStatement(sql), collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, T list, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toCollection(getPreparedStatement(sql), list, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E> T toMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMap(getPreparedStatement(sql), map, mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapCollection(getPreparedStatement(sql), returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapCollection(getPreparedStatement(sql), map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ListIterator<T> toListIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return super.toListIterator(getPreparedStatement(sql), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterator<T> toIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return super.toIterator(getPreparedStatement(sql), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return super.toArray(getPreparedStatement(sql), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> toList(String sql, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toList(getPreparedStatement(sql), componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E> Map<K, E> toMap(String sql, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMap(getPreparedStatement(sql), mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(String sql, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapList(getPreparedStatement(sql), mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toCollectionMap(getPreparedStatement(sql), collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toCollectionMap(getPreparedStatement(sql), list, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapMap(getPreparedStatement(sql), returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapMap(getPreparedStatement(sql), map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapCollectionMap(getPreparedStatement(sql), returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapCollectionMap(getPreparedStatement(sql), map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toListIteratorMap(getPreparedStatement(sql), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toIteratorMap(getPreparedStatement(sql), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toArrayMap(getPreparedStatement(sql), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(String sql, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toListMap(getPreparedStatement(sql), componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapMap(getPreparedStatement(sql), mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapListMap(getPreparedStatement(sql), mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toListIteratorMap(getPreparedStatement(sql), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toIteratorMap(getPreparedStatement(sql), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> List<Map<String, V>> toListMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toListMap(getPreparedStatement(sql), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapMap(getPreparedStatement(sql), mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return super.toMapListMap(getPreparedStatement(sql), mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,138 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Maps the same as ResultSetMapper except caches constructor and field mappings
|
||||
*
|
||||
* @see ResultSetMapper
|
||||
*/
|
||||
public class CachingResultSetMapper extends ResultSetMapper {
|
||||
|
||||
protected final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache;
|
||||
/**
|
||||
* CachingResultSetMapper with optional maxEntries, expiring old ones in LRU fashion
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param maxEntries max cached compiled entries to keep in cache, < 1 means unlimited
|
||||
*/
|
||||
public CachingResultSetMapper(final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength);
|
||||
if (maxEntries > 0) { // we want a limited cache
|
||||
final float loadFactor = 0.75f; // default for HashMaps
|
||||
// if we set the initialCapacity this way, nothing should ever need re-sized
|
||||
final int initialCapacity = ((int) Math.ceil(maxEntries / loadFactor)) + 1;
|
||||
cache = new LinkedHashMap<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>>(initialCapacity, loadFactor, true) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(final Map.Entry<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
};
|
||||
} else
|
||||
cache = new HashMap<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with unlimited cache
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
*/
|
||||
public CachingResultSetMapper(final Calendar cal, final int arrayMaxLength) {
|
||||
this(cal, arrayMaxLength, 0); // default unlimited cache
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with unlimited cache
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
*/
|
||||
public CachingResultSetMapper(final int arrayMaxLength) {
|
||||
this(null, arrayMaxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with unlimited cache
|
||||
*/
|
||||
public CachingResultSetMapper() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CachingResultSetMapper(final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(cal, arrayMaxLength);
|
||||
if (cache == null)
|
||||
throw new IllegalArgumentException("cache cannot be null");
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CachingResultSetMapper(final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
this(null, arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CachingResultSetMapper(final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
this(-1, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CachingResultSetMapper(final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
this(cal, arrayMaxLength, threadSafe ?
|
||||
new ConcurrentHashMap<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>>()
|
||||
:
|
||||
new HashMap<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>>()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CachingResultSetMapper(final int arrayMaxLength, final boolean threadSafe) {
|
||||
this(null, arrayMaxLength, threadSafe);
|
||||
}
|
||||
|
||||
/**
|
||||
* CachingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CachingResultSetMapper(final boolean threadSafe) {
|
||||
this(-1, threadSafe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new CachingRowToObjectMapper<K, T>(cache, resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Maps same as RowToObjectMapper except caches constructor and field mappings
|
||||
*/
|
||||
public class CachingRowToObjectMapper<K, T> extends RowToObjectMapper<K, T> {
|
||||
|
||||
protected final Map<ResultSetKey, FieldMapping<T>> cache;
|
||||
protected final ResultSetKey keys;
|
||||
|
||||
public CachingRowToObjectMapper(final Map<ResultSetKey, FieldMapping<?>> cache, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
super(resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<ResultSetKey, FieldMapping<T>> genericCache = (Map<ResultSetKey, FieldMapping<T>>) (Object) cache; // ridiculous ain't it?
|
||||
this.cache = genericCache;
|
||||
try {
|
||||
keys = new ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass, _mapKeyType);
|
||||
//System.out.printf("keys: %s\n", keys);
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException("CachingRowToObjectMapper: SQLException: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getKeysFromResultSet() throws SQLException {
|
||||
return keys.keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getFieldMappings() throws SQLException {
|
||||
final FieldMapping<T> fm = cache.get(keys);
|
||||
if (fm == null) {
|
||||
//System.out.printf("cache miss, keys: %s\n", keys);
|
||||
// generate and put into cache
|
||||
super.getFieldMappings();
|
||||
cache.put(keys, new FieldMapping<T>(_fields, _fieldTypes, resultSetConstructor, constructor));
|
||||
} else {
|
||||
//System.out.printf("cache hit, keys: %s\n", keys);
|
||||
// load from cache
|
||||
_fields = fm._fields;
|
||||
_fieldTypes = fm._fieldTypes;
|
||||
resultSetConstructor = fm.resultSetConstructor;
|
||||
constructor = fm.constructor;
|
||||
constructorLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ResultSetKey {
|
||||
protected final String[] keys;
|
||||
protected final Class<?> returnTypeClass, mapKeyType;
|
||||
|
||||
public ResultSetKey(final String[] keys, final Class<?> returnTypeClass, final Class<?> mapKeyType) {
|
||||
this.keys = keys;
|
||||
this.returnTypeClass = returnTypeClass;
|
||||
this.mapKeyType = mapKeyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ResultSetKey)) return false;
|
||||
|
||||
final ResultSetKey that = (ResultSetKey) o;
|
||||
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(keys, that.keys)) return false;
|
||||
if (returnTypeClass != null ? !returnTypeClass.equals(that.returnTypeClass) : that.returnTypeClass != null)
|
||||
return false;
|
||||
return mapKeyType != null ? mapKeyType.equals(that.mapKeyType) : that.mapKeyType == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Arrays.hashCode(keys);
|
||||
result = 31 * result + (returnTypeClass != null ? returnTypeClass.hashCode() : 0);
|
||||
result = 31 * result + (mapKeyType != null ? mapKeyType.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResultSetKey{" +
|
||||
"keys=" + Arrays.toString(keys) +
|
||||
", returnTypeClass=" + returnTypeClass +
|
||||
", mapKeyType=" + mapKeyType +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
static class FieldMapping<T> {
|
||||
public final AccessibleObject[] _fields;
|
||||
public final int[] _fieldTypes;
|
||||
public final boolean resultSetConstructor;
|
||||
public final Constructor<? extends T> constructor;
|
||||
|
||||
public FieldMapping(final AccessibleObject[] _fields, final int[] _fieldTypes, final boolean resultSetConstructor, final Constructor<? extends T> constructor) {
|
||||
this._fields = _fields;
|
||||
this._fieldTypes = _fieldTypes;
|
||||
this.resultSetConstructor = resultSetConstructor;
|
||||
this.constructor = constructor;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/15/14.
|
||||
*/
|
||||
public class CaseInsensitiveMapResultSetMapper extends ResultSetMapper {
|
||||
public CaseInsensitiveMapResultSetMapper() {
|
||||
}
|
||||
|
||||
public CaseInsensitiveMapResultSetMapper(int arrayMaxLength) {
|
||||
super(arrayMaxLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new RowToObjectMapper<K, T>(resultSet, returnTypeClass, cal, mapValType, mapKeyType, true);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
public interface Cleaner<T> {
|
||||
|
||||
public T clean(T dto);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CleaningCachingResultSetMapper<E> extends CachingResultSetMapper {
|
||||
|
||||
private final Cleaner<E> cleaner;
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength, maxEntries);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength) {
|
||||
super(arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner) {
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache) {
|
||||
super(cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(cal, arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCachingResultSetMapper(final Cleaner<E> cleaner, final boolean threadSafe) {
|
||||
super(threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, T> RowMapper<K, T> getRowMapper(final ResultSet resultSet, final Class<T> returnTypeClass, final Calendar cal, final Class<?> mapValType, final Class<K> mapKeyType) {
|
||||
return new CleaningRowToObjectMapper((Cleaner<T>)cleaner, super.getRowMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType));
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CleaningCompilingResultSetMapper<E> extends CompilingResultSetMapper {
|
||||
|
||||
private final Cleaner<E> cleaner;
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength, maxEntries);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength) {
|
||||
super(arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner) {
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(arrayMaxLength, cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?, ?>> cache) {
|
||||
super(cache);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(cal, arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final int arrayMaxLength, final boolean threadSafe) {
|
||||
super(arrayMaxLength, threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningCompilingResultSetMapper(final Cleaner<E> cleaner, final boolean threadSafe) {
|
||||
super(threadSafe);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, T> RowMapper<K, T> getRowMapper(final ResultSet resultSet, final Class<T> returnTypeClass, final Calendar cal, final Class<?> mapValType, final Class<K> mapKeyType) {
|
||||
return new CleaningRowToObjectMapper((Cleaner<T>)cleaner, super.getRowMapper(resultSet, returnTypeClass, cal, mapValType, mapKeyType));
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class CleaningResultSetMapper<E> extends ResultSetMapper {
|
||||
|
||||
private final Cleaner<E> cleaner;
|
||||
|
||||
public CleaningResultSetMapper(Cleaner<E> cleaner, Calendar cal, int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength);
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
public CleaningResultSetMapper(Cleaner<E> cleaner) {
|
||||
super();
|
||||
this.cleaner = cleaner;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new CleaningRowToObjectMapper<K, T>((Cleaner<T>)cleaner, resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class CleaningRowToObjectMapper<K, T> implements RowMapper<K, T> {
|
||||
|
||||
private final Cleaner<T> cleaner;
|
||||
private final RowMapper<K,T> delegate;
|
||||
|
||||
public CleaningRowToObjectMapper(Cleaner<T> cleaner, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
this(cleaner, new RowToObjectMapper<K, T>(resultSet, returnTypeClass, cal, mapValType, mapKeyType));
|
||||
}
|
||||
|
||||
public CleaningRowToObjectMapper(final Cleaner<T> cleaner, final RowMapper<K,T> delegate) {
|
||||
this.cleaner = cleaner;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T mapRowToReturnType() throws SQLException {
|
||||
return cleaner.clean(delegate.mapRowToReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getMapKey() throws SQLException {
|
||||
return delegate.getMapKey();
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.classgen.Compiler;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* This generally follows the contract of ResultSetMapper, with the differences specified in CompilingRowToObjectMapper.
|
||||
* <p>
|
||||
* This does cache compiled code based on column name/order and DTO being mapped to, so the (rather heavy)
|
||||
* code generation/compilation/instantiation only happens once for each query/dto, and is very fast on subsequent calls.
|
||||
* <p>
|
||||
* By default this uses a plain HashMap for the cache, unbounded, and not thread-safe. There are overloaded constructors
|
||||
* you can use to tell it to be threadSafe in which case it uses an unbounded ConcurrentHashMap, or to give it a maxEntries
|
||||
* in which case it uses a LinkedHashMap and clears out old entries in LRU order keeping only maxEntries. Lastly you can
|
||||
* send in your own custom Map implementation, CompilingResultSetMapper guarantees null will never be used for key or value.
|
||||
*
|
||||
* @see CompilingRowToObjectMapper
|
||||
*/
|
||||
public class CompilingResultSetMapper extends ResultSetMapper {
|
||||
|
||||
protected final Compiler compiler = new Compiler();
|
||||
protected final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> cache;
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with optional maxEntries, expiring old ones in LRU fashion
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param maxEntries max cached compiled entries to keep in cache, < 1 means unlimited
|
||||
*/
|
||||
public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final int maxEntries) {
|
||||
super(cal, arrayMaxLength);
|
||||
if (maxEntries > 0) { // we want a limited cache
|
||||
final float loadFactor = 0.75f; // default for HashMaps
|
||||
// if we set the initialCapacity this way, nothing should ever need re-sized
|
||||
final int initialCapacity = ((int) Math.ceil(maxEntries / loadFactor)) + 1;
|
||||
cache = new LinkedHashMap<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>>(initialCapacity, loadFactor, true) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(final Map.Entry<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> eldest) {
|
||||
return size() > maxEntries;
|
||||
}
|
||||
};
|
||||
} else
|
||||
cache = new HashMap<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with unlimited cache
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
*/
|
||||
public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength) {
|
||||
this(cal, arrayMaxLength, 0); // default unlimited cache
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with unlimited cache
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
*/
|
||||
public CompilingResultSetMapper(final int arrayMaxLength) {
|
||||
this(null, arrayMaxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with unlimited cache
|
||||
*/
|
||||
public CompilingResultSetMapper() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> cache) {
|
||||
super(cal, arrayMaxLength);
|
||||
if (cache == null)
|
||||
throw new IllegalArgumentException("cache cannot be null");
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CompilingResultSetMapper(final int arrayMaxLength, final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> cache) {
|
||||
this(null, arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with custom cache implementation
|
||||
*
|
||||
* @param cache any Map implementation for cache you wish, does not need to handle null keys or values
|
||||
*/
|
||||
public CompilingResultSetMapper(final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> cache) {
|
||||
this(-1, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param cal optional calendar for date/time values
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CompilingResultSetMapper(final Calendar cal, final int arrayMaxLength, final boolean threadSafe) {
|
||||
this(cal, arrayMaxLength, threadSafe ?
|
||||
new ConcurrentHashMap<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>>()
|
||||
:
|
||||
new HashMap<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>>()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param arrayMaxLength max array/list/map length, a value of less than 1 indicates that all rows from the ResultSet should be included
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CompilingResultSetMapper(final int arrayMaxLength, final boolean threadSafe) {
|
||||
this(null, arrayMaxLength, threadSafe);
|
||||
}
|
||||
|
||||
/**
|
||||
* CompilingResultSetMapper with optionally threadSafe cache implementation
|
||||
*
|
||||
* @param threadSafe true uses a thread-safe cache implementation (currently ConcurrentHashMap), false uses regular HashMap
|
||||
*/
|
||||
public CompilingResultSetMapper(final boolean threadSafe) {
|
||||
this(-1, threadSafe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new CompilingRowToObjectMapper<K, T>(compiler, cache, resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
}
|
@ -1,417 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.classgen.Compiler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* a compilation and therefore mapping error.
|
||||
*/
|
||||
public class CompilingRowToObjectMapper<K, T> extends RowToObjectMapper<K, T> {
|
||||
|
||||
// do not remove, used from generated classes
|
||||
public static final String firstColumnError = "Cannot call getFirstColumn when mapKeyType is null!";
|
||||
|
||||
protected final Compiler compiler;
|
||||
protected final ResultSetToObject<K, T> resultSetToObject;
|
||||
|
||||
public CompilingRowToObjectMapper(final Compiler compiler, final Map<CachingRowToObjectMapper.ResultSetKey, ResultSetToObject<?,?>> cache, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
this(compiler, cache, resultSet, returnTypeClass, cal, mapValType, mapKeyType, false);
|
||||
}
|
||||
|
||||
public CompilingRowToObjectMapper(final Compiler compiler, final Map<CachingRowToObjectMapper.ResultSetKey, ResultSetToObject<?,?>> cache, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType, final boolean caseInsensitiveMap) {
|
||||
super(resultSet, returnTypeClass, cal, mapValType, mapKeyType, caseInsensitiveMap);
|
||||
this.compiler = compiler;
|
||||
try {
|
||||
final CachingRowToObjectMapper.ResultSetKey keys = new CachingRowToObjectMapper.ResultSetKey(super.getKeysFromResultSet(), _returnTypeClass, _mapKeyType);
|
||||
//System.out.printf("keys: %s\n", keys);
|
||||
@SuppressWarnings("unchecked")
|
||||
final ResultSetToObject<K,T> resultSetToObject = (ResultSetToObject<K,T>) cache.get(keys);
|
||||
if (resultSetToObject == null) {
|
||||
//System.out.printf("cache miss, keys: %s\n", keys);
|
||||
// generate and put into cache
|
||||
cache.put(keys, this.resultSetToObject = genClass());
|
||||
this.keys = null;
|
||||
this._fields = null;
|
||||
this._fieldTypes = null;
|
||||
this.constructor = null;
|
||||
} 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);
|
||||
} catch (IOException e) {
|
||||
throw new MapperException("CachingRowToObjectMapper: IOException (should never happen?): " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T mapRowToReturnType() throws SQLException {
|
||||
return resultSetToObject.toObject(_resultSet, _cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getMapKey() throws SQLException {
|
||||
return resultSetToObject.getFirstColumn(_resultSet, _cal);
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
|
||||
public interface ResultSetToObject<K, T> {
|
||||
K getFirstColumn(final ResultSet rs, final Calendar cal) throws SQLException;
|
||||
T toObject(final ResultSet rs, final Calendar cal) throws SQLException;
|
||||
}
|
||||
|
||||
protected String typeFromName(final Class<?> type) {
|
||||
if(type == null)
|
||||
return "Object";
|
||||
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) {
|
||||
return type.getName();
|
||||
} else {
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String escapeMapKeyString(final String s) {
|
||||
// todo: escape key string, newlines, double quotes, backslashes...
|
||||
// actually it seems like those wouldn't be valid SQL column names, so we won't bother until we hear different...
|
||||
return '"' + s + '"';
|
||||
}
|
||||
|
||||
// code generation down here
|
||||
protected ResultSetToObject<K, T> genClass() throws IOException {
|
||||
final String className = "CompilingMapper";
|
||||
final String tType = typeFromName(_returnTypeClass);
|
||||
final String kType = typeFromName(_mapKeyType);
|
||||
final String header =
|
||||
"import static com.moparisthebest.jdbc.util.ResultSetUtil.*;\n\n" +
|
||||
"public final class " + className +
|
||||
" implements com.moparisthebest.jdbc.CompilingRowToObjectMapper.ResultSetToObject<"+ kType +"," + tType + "> {\n" +
|
||||
" public " + tType + " toObject(final java.sql.ResultSet rs, final java.util.Calendar cal) throws java.sql.SQLException {\n";
|
||||
final String footer = ";\n }\n" +
|
||||
"}\n";
|
||||
|
||||
final StringBuilder java = new StringBuilder(header);
|
||||
//java.append("return null;\n");
|
||||
gen(java, tType);
|
||||
java.append("return ret;\n");
|
||||
|
||||
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 ");
|
||||
extractColumnValueString(java, 1, _mapKeyType);
|
||||
} else {
|
||||
java.append("throw new com.moparisthebest.jdbc.MapperException(com.moparisthebest.jdbc.CompilingRowToObjectMapper.firstColumnError)");
|
||||
}
|
||||
|
||||
java.append(footer);
|
||||
//System.out.println(java);
|
||||
return compiler.compile(className, java);
|
||||
}
|
||||
|
||||
public void gen(final Appendable java, final String tType) throws IOException {
|
||||
|
||||
if(mapOnlySecondColumn){
|
||||
java.append("final ").append(tType).append(" ret = ");
|
||||
extractColumnValueString(java, 2, _tmf.getTypeId(_returnTypeClass));
|
||||
java.append(";\n");
|
||||
return;
|
||||
}
|
||||
|
||||
lazyLoadConstructor();
|
||||
|
||||
if (resultSetConstructor) {
|
||||
java.append("final ").append(tType).append(" ret = new ").append(tType).append("(rs);\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnMap) // we want a map
|
||||
try {
|
||||
// todo: does not call getMapImplementation, I think that's fine
|
||||
java.append("final ").append(tType).append("<String, Object> ret = new ").append(tType).append("<String, Object>();\n");
|
||||
final int columnLength = _columnCount + 1;
|
||||
if (componentType != null && componentType != Object.class) { // we want a specific value type
|
||||
int typeId = _tmf.getTypeId(componentType);
|
||||
for (int x = 1; x < columnLength; ++x) {
|
||||
java.append("ret.put(").append(escapeMapKeyString(keys[x]).toLowerCase()).append(", ");
|
||||
extractColumnValueString(java, x, typeId);
|
||||
java.append(");\n");
|
||||
}
|
||||
} else // we want a generic object type
|
||||
for (int x = 1; x < columnLength; ++x)
|
||||
java.append("ret.put(").append(escapeMapKeyString(keys[x].toLowerCase())).append(", rs.getObject(").append(String.valueOf(x)).append("));\n");
|
||||
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 {
|
||||
java.append("final ").append(tType).append(" ret = new ").append(tType.substring(0, tType.length() - 1)).append(String.valueOf(_columnCount)).append("];\n");
|
||||
final int typeId = _tmf.getTypeId(componentType);
|
||||
for (int x = 0; x < _columnCount; ) {
|
||||
java.append("ret[").append(String.valueOf(x)).append("] = ");
|
||||
extractColumnValueString(java, ++x, typeId);
|
||||
java.append(";\n");
|
||||
}
|
||||
return;
|
||||
} 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) {
|
||||
java.append("final ").append(tType).append(" ret = ");
|
||||
extractColumnValueString(java, 1, typeId);
|
||||
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?
|
||||
java.append("final ").append(tType).append(" ret = (").append(tType).append(") ");
|
||||
extractColumnValueString(java, 1, typeId);
|
||||
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];
|
||||
|
||||
//_args[0] = extractColumnValue(i, _fieldTypes[i]);
|
||||
//System.out.printf("field: '%s' obj: '%s' fieldType: '%s'\n", _fields[i], _args[0], _fieldTypes[i]);
|
||||
// custom hacked-in support for enums, can do better when we scrap org.apache.beehive.controls.system.jdbc.TypeMappingsFactory
|
||||
if (_fieldTypes[i] == 0) {
|
||||
final Class<?> fieldType = f instanceof Field ? ((Field) f).getType() : ((Method) f).getParameterTypes()[0];
|
||||
if (Enum.class.isAssignableFrom(fieldType)) {
|
||||
_args[0] = Enum.valueOf((Class<? extends Enum>) fieldType, (String) _args[0]);
|
||||
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(" = ").append(typeFromName(fieldType)).append(".valueOf(");
|
||||
extractColumnValueString(java, i, _fieldTypes[i]);
|
||||
java.append(");\n");
|
||||
} else {
|
||||
java.append("ret.").append(((Method) f).getName()).append("(").append(typeFromName(fieldType)).append(".valueOf(");
|
||||
extractColumnValueString(java, i, _fieldTypes[i]);
|
||||
java.append("));\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
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(" = ");
|
||||
extractColumnValueString(java, i, _fieldTypes[i]);
|
||||
java.append(";\n");
|
||||
} else {
|
||||
java.append("ret.").append(((Method) f).getName()).append("(");
|
||||
extractColumnValueString(java, i, _fieldTypes[i]);
|
||||
java.append(");\n");
|
||||
}
|
||||
}
|
||||
// if this resultObject is Finishable, call finish()
|
||||
if (Finishable.class.isAssignableFrom(_returnTypeClass))
|
||||
java.append("ret.finish(rs);\n");
|
||||
}
|
||||
|
||||
|
||||
public void extractColumnValueString(final Appendable java, final int index, final Class resultType) throws IOException {
|
||||
extractColumnValueString(java, index, _tmf.getTypeId(resultType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void extractColumnValueString(final Appendable java, final int index, final int resultType) throws IOException {
|
||||
switch (resultType) {
|
||||
case TypeMappingsFactory.TYPE_INT:
|
||||
java.append("rs.getInt(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_LONG:
|
||||
java.append("rs.getLong(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_FLOAT:
|
||||
java.append("rs.getFloat(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_DOUBLE:
|
||||
java.append("rs.getDouble(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BYTE:
|
||||
java.append("rs.getByte(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_SHORT:
|
||||
java.append("rs.getInt(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN:
|
||||
java.append("getBooleanYN(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_INT_OBJ:
|
||||
java.append("getObjectInt(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_LONG_OBJ:
|
||||
java.append("getObjectLong(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_FLOAT_OBJ:
|
||||
java.append("getObjectFloat(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_DOUBLE_OBJ:
|
||||
java.append("getObjectDouble(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BYTE_OBJ:
|
||||
java.append("getObjectByte(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_SHORT_OBJ:
|
||||
java.append("getObjectShort(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN_OBJ:
|
||||
java.append("getObjectBooleanYN(rs, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_STRING:
|
||||
case TypeMappingsFactory.TYPE_XMLBEAN_ENUM:
|
||||
java.append("rs.getString(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BIG_DECIMAL:
|
||||
java.append("rs.getBigDecimal(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BYTES:
|
||||
java.append("rs.getBytes(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_TIMESTAMP:
|
||||
java.append("getTimestamp(rs, cal, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_TIME:
|
||||
java.append("getTime(rs, cal, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_SQLDATE:
|
||||
java.append("getSqlDate(rs, cal, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_DATE:
|
||||
java.append("getUtilDate(rs, cal, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_CALENDAR:
|
||||
java.append("getCalendar(rs, cal, ").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_REF:
|
||||
java.append("rs.getRef(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_BLOB:
|
||||
java.append("rs.getBlob(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_CLOB:
|
||||
java.append("rs.getClob(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_ARRAY:
|
||||
java.append("rs.getArray(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
case TypeMappingsFactory.TYPE_READER:
|
||||
case TypeMappingsFactory.TYPE_STREAM:
|
||||
throw new MapperException("streaming return types are not supported by the JdbcControl; use ResultSet instead");
|
||||
case TypeMappingsFactory.TYPE_STRUCT:
|
||||
case TypeMappingsFactory.TYPE_UNKNOWN:
|
||||
// JAVA_TYPE (could be any), or REF
|
||||
java.append("rs.getObject(").append(String.valueOf(index)).append(")");
|
||||
return;
|
||||
default:
|
||||
throw new MapperException("internal error: unknown type ID: " + Integer.toString(resultType));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface Finishable {
|
||||
public void finish(ResultSet rs) throws SQLException;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* For a column name and a Collection, return a Object usable by QueryMapper for binding to a PreparedStatement and
|
||||
* ListQueryMapper for substituting in the query
|
||||
*/
|
||||
public interface InList {
|
||||
|
||||
/**
|
||||
* Returns an Object who's .toString returns a String for a query, and QueryMapper knows how to bind to a PreparedStatement
|
||||
* @param columnName Column name for query
|
||||
* @param values values for in list
|
||||
* @return object
|
||||
*/
|
||||
public <T> InListObject inList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException;
|
||||
|
||||
class InListObject {
|
||||
static final InListObject empty = new InListObject("(0=1)");
|
||||
|
||||
private final String sql;
|
||||
|
||||
public InListObject(final String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,544 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class ListQueryMapper extends QueryMapper {
|
||||
|
||||
private static final InList defaultInList;
|
||||
|
||||
static {
|
||||
InList def = null;
|
||||
try {
|
||||
final Class<?> ensureContext = Class.forName(System.getProperty("QueryMapper.defaultInList.class", "com.moparisthebest.jdbc.BindInList"));
|
||||
final Method method = ensureContext.getMethod(System.getProperty("QueryMapper.defaultInList.method", "instance"));
|
||||
def = (InList) method.invoke(null);
|
||||
} catch (Throwable e) {
|
||||
// NEVER ignore
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
defaultInList = def;
|
||||
}
|
||||
|
||||
protected final QueryMapper delegate;
|
||||
protected final InList inList;
|
||||
|
||||
public static final String inListReplace = "{inList}";
|
||||
|
||||
private ListQueryMapper(Connection conn, String jndiName, QueryMapper delegate, ResultSetMapper cm, InList inList) {
|
||||
this.inList = inList;
|
||||
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, cm) :
|
||||
(delegate instanceof ListQueryMapper ? ((ListQueryMapper)delegate).delegate : delegate);
|
||||
}
|
||||
|
||||
public ListQueryMapper(QueryMapper delegate, InList inList) {
|
||||
this(null, null, delegate, null, inList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(QueryMapper delegate) {
|
||||
this(null, null, delegate, null, defaultInList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(Connection conn, InList inList) {
|
||||
this(conn, null, null, null, inList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(Connection conn, ResultSetMapper cm, InList inList) {
|
||||
this(conn, null, null, cm, inList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(Connection conn) {
|
||||
this(conn, defaultInList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(Connection conn, ResultSetMapper cm) {
|
||||
this(conn, cm, defaultInList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(String jndiName, InList inList) {
|
||||
this(null, jndiName, null, null, inList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(String jndiName, ResultSetMapper cm, InList inList) {
|
||||
this(null, jndiName, null, cm, inList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(String jndiName) {
|
||||
this(jndiName, defaultInList);
|
||||
}
|
||||
|
||||
public ListQueryMapper(String jndiName, ResultSetMapper cm) {
|
||||
this(jndiName, cm, defaultInList);
|
||||
}
|
||||
|
||||
public static ListQueryMapper wrap(final QueryMapper qm){
|
||||
return qm instanceof ListQueryMapper ? (ListQueryMapper)qm : new ListQueryMapper(qm);
|
||||
}
|
||||
|
||||
public static ListQueryMapper wrap(final QueryMapper qm, final InList inList){
|
||||
return qm instanceof ListQueryMapper && ((ListQueryMapper)qm).inList == inList ? (ListQueryMapper)qm : new ListQueryMapper(qm, inList);
|
||||
}
|
||||
|
||||
public <T> InList.InListObject inList(final String columnName, final Collection<T> values) throws SQLException {
|
||||
return this.inList.inList(delegate.conn, columnName, values);
|
||||
}
|
||||
|
||||
// these update the database
|
||||
|
||||
@Override
|
||||
public int executeUpdate(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return delegate.executeUpdate(ps, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUpdateSuccess(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return delegate.executeUpdateSuccess(ps, bindObjects);
|
||||
}
|
||||
|
||||
// these update the database using UpdateableDTOs
|
||||
|
||||
@Override
|
||||
public int updateRows(final UpdateableDTO dto) throws SQLException {
|
||||
return delegate.updateRows(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateRows(final Collection<UpdateableDTO> dtos) throws SQLException {
|
||||
return delegate.updateRows(dtos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateRows(final UpdateableDTO[] dtos) throws SQLException {
|
||||
return delegate.updateRows(dtos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(final UpdateableDTO dto) throws SQLException {
|
||||
return delegate.insertRows(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(final Collection<UpdateableDTO> dtos) throws SQLException {
|
||||
return delegate.insertRows(dtos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(final UpdateableDTO[] dtos) throws SQLException {
|
||||
return delegate.insertRows(dtos);
|
||||
}
|
||||
|
||||
// these grab ResultSets from the database
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(PreparedStatement ps, Object... bindObjects) throws SQLException {
|
||||
return delegate.toResultSet(ps, bindObjects);
|
||||
}
|
||||
|
||||
// these are standard getters
|
||||
|
||||
@Override
|
||||
public ResultSetMapper getCustomResultSetMapper() {
|
||||
return delegate.getCustomResultSetMapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return delegate.getConnection();
|
||||
}
|
||||
|
||||
// these just delegate and change no functionality
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
// and these are standard
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final ListQueryMapper that = (ListQueryMapper) o;
|
||||
|
||||
if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
|
||||
if (inList != null ? !inList.equals(that.inList) : that.inList != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = delegate != null ? delegate.hashCode() : 0;
|
||||
result = 31 * result + (inList != null ? inList.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ListQueryMapper{" +
|
||||
"delegate=" + delegate +
|
||||
", inList=" + inList +
|
||||
"} " + super.toString();
|
||||
}
|
||||
|
||||
// begin of ListQueryMapper specific methods
|
||||
|
||||
private static StringBuilder recursiveReplace(final StringBuilder sb, final Object... bindObjects) {
|
||||
if (bindObjects != null && bindObjects.length > 0) {
|
||||
for (Object o : bindObjects) {
|
||||
if (o != null && o != QueryMapper.noBind) {
|
||||
if (o instanceof InList.InListObject) {
|
||||
final int startIndex = sb.indexOf(inListReplace);
|
||||
if (startIndex < -1)
|
||||
return sb; // we've replaced all, maybe an error? meh
|
||||
sb.replace(startIndex, startIndex + inListReplace.length(), o.toString());
|
||||
} else if (o instanceof Object[]) {
|
||||
recursiveReplace(sb, (Object[]) o);
|
||||
} else if (o instanceof Collection) {
|
||||
recursiveReplace(sb, ((Collection) o).toArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected String prepareSql(final String sql, final Object... bindObjects) {
|
||||
return !sql.contains(inListReplace) ? sql : recursiveReplace(new StringBuilder(sql), bindObjects).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(final String sql, final Object... bindObjects) throws SQLException {
|
||||
return delegate.executeUpdate(prepareSql(sql, bindObjects), bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUpdateSuccess(final String sql, final Object... bindObjects) throws SQLException {
|
||||
return delegate.executeUpdateSuccess(prepareSql(sql, bindObjects), bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(String sql, Object... bindObjects) throws SQLException {
|
||||
return delegate.toResultSet(prepareSql(sql, bindObjects), bindObjects);
|
||||
}
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||
|
||||
@Override
|
||||
public <T> T toObject(PreparedStatement ps, Class<T> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toObject(ps, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toObject(String sql, Class<T> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toObject(prepareSql(sql, bindObjects), componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(PreparedStatement ps, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toSingleMap(ps, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(String sql, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toSingleMap(prepareSql(sql, bindObjects), componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Map<String, V> toSingleMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toSingleMap(ps, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Map<String, V> toSingleMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toSingleMap(prepareSql(sql, bindObjects), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement ps, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollection(ps, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollection(prepareSql(sql, bindObjects), collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement ps, T list, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollection(ps, list, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, T list, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollection(prepareSql(sql, bindObjects), list, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E> T toMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMap(ps, map, mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E> T toMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMap(prepareSql(sql, bindObjects), map, mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollection(ps, returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollection(prepareSql(sql, bindObjects), returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollection(ps, map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollection(prepareSql(sql, bindObjects), map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ListIterator<T> toListIterator(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIterator(ps, type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ListIterator<T> toListIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIterator(prepareSql(sql, bindObjects), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterator<T> toIterator(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIterator(ps, type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterator<T> toIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIterator(prepareSql(sql, bindObjects), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toArray(ps, type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toArray(prepareSql(sql, bindObjects), type, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> toList(PreparedStatement ps, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toList(ps, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> toList(String sql, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toList(prepareSql(sql, bindObjects), componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E> Map<K, E> toMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMap(ps, mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E> Map<K, E> toMap(String sql, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMap(prepareSql(sql, bindObjects), mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(PreparedStatement ps, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapList(ps, mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(String sql, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapList(prepareSql(sql, bindObjects), mapKeyType, componentType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement ps, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollectionMap(ps, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollectionMap(prepareSql(sql, bindObjects), collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement ps, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollectionMap(ps, list, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toCollectionMap(prepareSql(sql, bindObjects), list, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(ps, returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(prepareSql(sql, bindObjects), returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(ps, map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(prepareSql(sql, bindObjects), map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollectionMap(ps, returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollectionMap(prepareSql(sql, bindObjects), returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollectionMap(ps, map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapCollectionMap(prepareSql(sql, bindObjects), map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIteratorMap(ps, type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIteratorMap(prepareSql(sql, bindObjects), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIteratorMap(ps, type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIteratorMap(prepareSql(sql, bindObjects), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toArrayMap(ps, type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toArrayMap(prepareSql(sql, bindObjects), type, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(PreparedStatement ps, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListMap(ps, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(String sql, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListMap(prepareSql(sql, bindObjects), componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(ps, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(prepareSql(sql, bindObjects), mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapListMap(ps, mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapListMap(prepareSql(sql, bindObjects), mapKeyType, componentType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIteratorMap(ps, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListIteratorMap(prepareSql(sql, bindObjects), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIteratorMap(ps, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toIteratorMap(prepareSql(sql, bindObjects), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> List<Map<String, V>> toListMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListMap(ps, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> List<Map<String, V>> toListMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toListMap(prepareSql(sql, bindObjects), mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(PreparedStatement ps, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(ps, mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapMap(prepareSql(sql, bindObjects), mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement ps, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapListMap(ps, mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return delegate.toMapListMap(prepareSql(sql, bindObjects), mapKeyType, mapValType, bindObjects);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
/**
|
||||
* The MapperException class declares an unchecked exception that is thrown by the Controls
|
||||
* runtime under certain failure conditions.
|
||||
*/
|
||||
public class MapperException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public MapperException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a MapperException object with the specified String as a message.
|
||||
*
|
||||
* @param message The message to use.
|
||||
*/
|
||||
public MapperException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a MapperException with the specified cause.
|
||||
* @param t the cause
|
||||
*/
|
||||
public MapperException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a MapperException object using the specified String as a message, and the
|
||||
* specified Throwable as a nested exception.
|
||||
*
|
||||
* @param message The message to use.
|
||||
* @param t The exception to nest within this exception.
|
||||
*/
|
||||
public MapperException(String message, Throwable t)
|
||||
{
|
||||
super(message + "[" + t + "]", t);
|
||||
}
|
||||
}
|
@ -1,861 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class NullQueryMapper extends QueryMapper {
|
||||
|
||||
protected final boolean verbose;
|
||||
protected final QueryMapper delegate;
|
||||
|
||||
private NullQueryMapper(Connection conn, String jndiName, QueryMapper delegate, ResultSetMapper cm, boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
this.delegate = delegate == null ? new QueryMapper(conn, jndiName, cm) : delegate;
|
||||
}
|
||||
|
||||
public NullQueryMapper(QueryMapper delegate, boolean verbose) {
|
||||
this(null, null, delegate, null, verbose);
|
||||
}
|
||||
|
||||
public NullQueryMapper(QueryMapper delegate) {
|
||||
this(null, null, delegate, null, true);
|
||||
}
|
||||
|
||||
public NullQueryMapper(Connection conn, boolean verbose) {
|
||||
this(conn, null, null, null, verbose);
|
||||
}
|
||||
|
||||
public NullQueryMapper(Connection conn, ResultSetMapper cm, boolean verbose) {
|
||||
this(conn, null, null, cm, verbose);
|
||||
}
|
||||
|
||||
public NullQueryMapper(Connection conn) {
|
||||
this(conn, true);
|
||||
}
|
||||
|
||||
public NullQueryMapper(Connection conn, ResultSetMapper cm) {
|
||||
this(conn, cm, true);
|
||||
}
|
||||
|
||||
public NullQueryMapper(String jndiName, boolean verbose) {
|
||||
this(null, jndiName, null, null, verbose);
|
||||
}
|
||||
|
||||
public NullQueryMapper(String jndiName, ResultSetMapper cm, boolean verbose) {
|
||||
this(null, jndiName, null, cm, verbose);
|
||||
}
|
||||
|
||||
public NullQueryMapper(String jndiName) {
|
||||
this(jndiName, true);
|
||||
}
|
||||
|
||||
public NullQueryMapper(String jndiName, ResultSetMapper cm) {
|
||||
this(jndiName, cm, true);
|
||||
}
|
||||
|
||||
public static NullQueryMapper wrap(final QueryMapper qm){
|
||||
return qm instanceof NullQueryMapper ? (NullQueryMapper)qm : new NullQueryMapper(qm);
|
||||
}
|
||||
|
||||
// these update the database
|
||||
|
||||
@Override
|
||||
public int executeUpdate(PreparedStatement ps, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.executeUpdate(ps, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUpdateSuccess(PreparedStatement ps, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.executeUpdateSuccess(ps, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.executeUpdate(sql, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUpdateSuccess(String sql, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.executeUpdateSuccess(sql, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// these update the database using UpdateableDTOs
|
||||
|
||||
@Override
|
||||
public int updateRows(UpdateableDTO dto) {
|
||||
try {
|
||||
return delegate.updateRows(dto);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateRows(Collection<UpdateableDTO> dtos) {
|
||||
try {
|
||||
return delegate.updateRows(dtos);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateRows(UpdateableDTO[] dtos) {
|
||||
try {
|
||||
return delegate.updateRows(dtos);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(UpdateableDTO dto) {
|
||||
try {
|
||||
return delegate.insertRows(dto);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(Collection<UpdateableDTO> dtos) {
|
||||
try {
|
||||
return delegate.insertRows(dtos);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRows(UpdateableDTO[] dtos) {
|
||||
try {
|
||||
return delegate.insertRows(dtos);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// these grab ResultSets from the database
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(PreparedStatement ps, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toResultSet(ps, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet toResultSet(String sql, Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toResultSet(sql, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// these are standard getters
|
||||
|
||||
@Override
|
||||
public ResultSetMapper getCustomResultSetMapper() {
|
||||
return delegate.getCustomResultSetMapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return delegate.getConnection();
|
||||
}
|
||||
|
||||
// these just delegate and change no functionality
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
// and these are standard
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
NullQueryMapper that = (NullQueryMapper) o;
|
||||
|
||||
if (verbose != that.verbose) return false;
|
||||
if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (verbose ? 1 : 0);
|
||||
result = 31 * result + (delegate != null ? delegate.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NullQueryMapper{" +
|
||||
"verbose=" + verbose +
|
||||
", delegate=" + delegate +
|
||||
"}";
|
||||
}
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||
|
||||
@Override
|
||||
public <T> T toObject(PreparedStatement query, Class<T> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toObject(query, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toObject(String query, Class<T> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toObject(query, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(PreparedStatement query, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toSingleMap(query, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(String query, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toSingleMap(query, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Map<String, V> toSingleMap(PreparedStatement query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toSingleMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Map<String, V> toSingleMap(String query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toSingleMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement query, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollection(query, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String query, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollection(query, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement query, T list, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollection(query, list, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E> T toCollection(String query, T list, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollection(query, list, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E> T toMap(PreparedStatement query, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMap(query, map, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E> T toMap(String query, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMap(query, map, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement query, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollection(query, returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String query, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollection(query, returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement query, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollection(query, map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String query, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollection(query, map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ListIterator<T> toListIterator(PreparedStatement query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIterator(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ListIterator<T> toListIterator(String query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIterator(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterator<T> toIterator(PreparedStatement query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIterator(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterator<T> toIterator(String query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIterator(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(PreparedStatement query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toArray(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(String query, final Class<T> type, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toArray(query, type, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> toList(PreparedStatement query, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toList(query, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> toList(String query, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toList(query, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E> Map<K, E> toMap(PreparedStatement query, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMap(query, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E> Map<K, E> toMap(String query, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMap(query, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(PreparedStatement query, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapList(query, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(String query, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapList(query, mapKeyType, componentType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement query, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollectionMap(query, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String query, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollectionMap(query, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement query, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollectionMap(query, list, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String query, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toCollectionMap(query, list, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement query, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String query, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement query, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String query, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement query, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollectionMap(query, returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String query, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollectionMap(query, returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement query, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollectionMap(query, map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String query, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapCollectionMap(query, map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIteratorMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(String query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIteratorMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIteratorMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(String query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIteratorMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(PreparedStatement query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toArrayMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(String query, final Class<T> type, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toArrayMap(query, type, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(PreparedStatement query, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListMap(query, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(String query, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListMap(query, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(PreparedStatement query, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(String query, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement query, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapListMap(query, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(String query, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapListMap(query, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIteratorMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(String query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListIteratorMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIteratorMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(String query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toIteratorMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> List<Map<String, V>> toListMap(PreparedStatement query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> List<Map<String, V>> toListMap(String query, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toListMap(query, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(PreparedStatement query, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, mapKeyType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(String query, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapMap(query, mapKeyType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement query, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapListMap(query, mapKeyType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(String query, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) {
|
||||
try {
|
||||
return delegate.toMapListMap(query, mapKeyType, mapValType, bindObjects);
|
||||
} catch (Throwable e) {
|
||||
if (verbose) e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Array;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by mopar on 4/29/15.
|
||||
*/
|
||||
public class OracleArrayInList extends ArrayInList {
|
||||
|
||||
private static final InList instance = new OracleArrayInList();
|
||||
|
||||
public static InList instance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static final Class<?> oracleConnection;
|
||||
private static final Method createArray;
|
||||
|
||||
static {
|
||||
Class<?> oc;
|
||||
Method ca;
|
||||
try {
|
||||
oc = Class.forName("oracle.jdbc.OracleConnection");
|
||||
ca = oc.getDeclaredMethod("createOracleArray", String.class, Object.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
oracleConnection = oc;
|
||||
createArray = ca;
|
||||
}
|
||||
|
||||
protected OracleArrayInList() {
|
||||
}
|
||||
|
||||
protected String columnAppend(final String columnName) {
|
||||
return "(" + columnName + " IN(select column_value from table(?)))";
|
||||
}
|
||||
|
||||
protected <T> Array toArray(final Connection conn, final Collection<T> values) throws SQLException {
|
||||
/*
|
||||
return conn.unwrap(oracle.jdbc.OracleConnection.class).createOracleArray(
|
||||
values.iterator().next() instanceof Number ? "ARRAY_NUM_TYPE" : "ARRAY_STR_TYPE",
|
||||
values.toArray()
|
||||
);
|
||||
*/
|
||||
try {
|
||||
return (Array) createArray.invoke(conn.unwrap(oracleConnection),
|
||||
values.iterator().next() instanceof Number ? "ARRAY_NUM_TYPE" : "ARRAY_STR_TYPE",
|
||||
values.toArray()
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e); // should never happen, but if it does don't hide it
|
||||
}
|
||||
}
|
||||
}
|
@ -1,788 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
|
||||
public class QueryMapper implements Closeable {
|
||||
|
||||
public static final Object noBind = new Object();
|
||||
|
||||
static {
|
||||
try{
|
||||
final Class<?> ensureContext = Class.forName(System.getProperty("QueryMapper.ensureContext.class", "com.gcl.containerless.EnsureContext"));
|
||||
final Method method = ensureContext.getMethod(System.getProperty("QueryMapper.ensureContext.method", "setup"));
|
||||
method.invoke(null);
|
||||
}catch(Throwable e){
|
||||
// ignore
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected final ResultSetMapper cm;
|
||||
protected final Connection conn;
|
||||
protected final Context context;
|
||||
|
||||
protected QueryMapper(Connection conn, String jndiName, ResultSetMapper cm) {
|
||||
this.cm = cm == null ? new ResultSetMapper() : cm;
|
||||
Context context = null;
|
||||
if (conn == null && jndiName != null)
|
||||
try {
|
||||
context = new InitialContext();
|
||||
DataSource ds = (DataSource) context.lookup(jndiName);
|
||||
conn = ds.getConnection();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
tryClose(conn);
|
||||
} finally {
|
||||
tryClose(context);
|
||||
}
|
||||
this.conn = conn;
|
||||
this.context = context;
|
||||
if (this.conn == null)
|
||||
throw new NullPointerException("Connection needs to be non-null for QueryMapper...");
|
||||
}
|
||||
|
||||
public QueryMapper(Connection conn, ResultSetMapper cm) {
|
||||
this(conn, null, cm);
|
||||
}
|
||||
|
||||
public QueryMapper(Connection conn) {
|
||||
this(conn, null);
|
||||
}
|
||||
|
||||
public QueryMapper(String jndiName, ResultSetMapper cm) {
|
||||
this(null, jndiName, cm);
|
||||
}
|
||||
|
||||
public QueryMapper(String jndiName) {
|
||||
this(jndiName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only meant to be called by implementing classes
|
||||
*/
|
||||
protected QueryMapper() {
|
||||
this.cm = null;
|
||||
this.conn = null;
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
tryClose(conn);
|
||||
tryClose(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StringWrapper {
|
||||
public final String s;
|
||||
|
||||
private StringWrapper(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StringWrapper)) return false;
|
||||
StringWrapper that = (StringWrapper) o;
|
||||
return !(s != null ? !s.equals(that.s) : that.s != null);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return s != null ? s.hashCode() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClobString extends StringWrapper {
|
||||
private ClobString(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlobString extends StringWrapper {
|
||||
private BlobString(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object wrapClob(String s) {
|
||||
return new ClobString(s);
|
||||
}
|
||||
|
||||
public static Object wrapBlob(String s) {
|
||||
return new BlobString(s);
|
||||
}
|
||||
|
||||
public static void setObject(final PreparedStatement ps, final int index, final Object o) throws SQLException {
|
||||
// we are going to put most common ones up top so it should execute faster normally
|
||||
if (o == null || o instanceof String || o instanceof Number)
|
||||
ps.setObject(index, o);
|
||||
// java.util.Date support, put it in a Timestamp
|
||||
else if (o instanceof java.util.Date)
|
||||
ps.setObject(index, o.getClass().equals(java.util.Date.class) ? new java.sql.Timestamp(((java.util.Date)o).getTime()) : o);
|
||||
// CLOB support
|
||||
else if (o instanceof Reader)
|
||||
ps.setClob(index, (Reader) o);
|
||||
else if (o instanceof ClobString)
|
||||
ps.setObject(index, ((ClobString) o).s == null ? null : ((ClobString) o).s);
|
||||
else if (o instanceof Clob)
|
||||
ps.setClob(index, (Clob) o);
|
||||
// BLOB support
|
||||
else if (o instanceof byte[])
|
||||
ps.setBlob(index, new ByteArrayInputStream((byte[]) o));
|
||||
else if (o instanceof InputStream)
|
||||
ps.setBlob(index, (InputStream) o);
|
||||
else if (o instanceof File)
|
||||
try {
|
||||
ps.setBlob(index, new FileInputStream((File) o));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SQLException("File to Blob FileNotFoundException", e);
|
||||
}
|
||||
else if (o instanceof BlobString)
|
||||
try {
|
||||
ps.setBlob(index, ((BlobString) o).s == null ? null : new ByteArrayInputStream(((BlobString) o).s.getBytes("UTF-8")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new SQLException("String to Blob UnsupportedEncodingException", e);
|
||||
}
|
||||
else if (o instanceof Blob)
|
||||
ps.setBlob(index, (Blob) o);
|
||||
else if (o instanceof ArrayInList.ArrayListObject)
|
||||
ps.setArray(index, ((ArrayInList.ArrayListObject) o).getArray());
|
||||
else
|
||||
ps.setObject(index, o); // probably won't get here ever, but just in case...
|
||||
/*
|
||||
switch(ps.getParameterMetaData().getParameterType(index)){ // 'java.sql.SQLException: Unsupported feature', fully JDBC 3.0 compliant my ass, freaking oracle...
|
||||
case Types.CLOB:
|
||||
if(o instanceof String)
|
||||
ps.setObject(index, o);
|
||||
else if (o instanceof Reader)
|
||||
ps.setClob(index, (Reader) o);
|
||||
else if (o instanceof Clob)
|
||||
ps.setClob(index, (Clob) o);
|
||||
return;
|
||||
case Types.BLOB:
|
||||
if (o instanceof byte[])
|
||||
ps.setBlob(index, new ByteArrayInputStream((byte[])o));
|
||||
else if (o instanceof InputStream)
|
||||
ps.setBlob(index, (InputStream) o);
|
||||
else if (o instanceof File)
|
||||
try {
|
||||
ps.setBlob(index, new FileInputStream((File) o));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SQLException("File to Blob FileNotFoundException", e);
|
||||
}
|
||||
else if (o instanceof Blob)
|
||||
ps.setBlob(index, (Blob) o);
|
||||
else if(o instanceof String)
|
||||
try{
|
||||
ps.setBlob(index, new ByteArrayInputStream(((String) o).getBytes("UTF-8")));
|
||||
}catch(UnsupportedEncodingException e){
|
||||
throw new SQLException("String to Blob UnsupportedEncodingException", e);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
ps.setObject(index, o);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public static int recursiveBind(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return recursiveBind(ps, 0, bindObjects);
|
||||
}
|
||||
|
||||
private static int recursiveBind(final PreparedStatement ps, int index, final Object... bindObjects) throws SQLException {
|
||||
if (bindObjects != null && bindObjects.length > 0) {
|
||||
for (Object o : bindObjects) {
|
||||
if (o != null) {
|
||||
if (o == InList.InListObject.empty || o == noBind) {
|
||||
continue; // ignore
|
||||
} else if (o instanceof BindInList.BindInListObject) {
|
||||
if (((BindInList.BindInListObject) o).getBindObjects() != null)
|
||||
index = recursiveBind(ps, index, ((BindInList.BindInListObject) o).getBindObjects());
|
||||
continue;
|
||||
} else if (o instanceof Object[]) {
|
||||
index = recursiveBind(ps, index, (Object[]) o);
|
||||
continue;
|
||||
} else if (o instanceof Collection) {
|
||||
index = recursiveBind(ps, index, ((Collection) o).toArray());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//System.out.printf("index: '%d' bound to '%s'\n", index+1, o);
|
||||
setObject(ps, ++index, o);
|
||||
//ps.setObject(++index, o);
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public static PreparedStatement bindStatement(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
recursiveBind(ps, bindObjects);
|
||||
return ps;
|
||||
}
|
||||
|
||||
protected PreparedStatement bind(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return bindStatement(ps, bindObjects);
|
||||
}
|
||||
|
||||
protected ResultSet bindExecute(final PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return bind(ps, bindObjects).executeQuery();
|
||||
}
|
||||
|
||||
// these update the database
|
||||
|
||||
public int executeUpdate(PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return bind(ps, bindObjects).executeUpdate();
|
||||
}
|
||||
|
||||
public boolean executeUpdateSuccess(PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return this.executeUpdate(ps, bindObjects) >= 0;
|
||||
}
|
||||
|
||||
public int executeUpdate(String sql, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.executeUpdate(ps, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean executeUpdateSuccess(String sql, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.executeUpdateSuccess(ps, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
// these update the database using UpdateableDTOs
|
||||
|
||||
public int updateRows(UpdateableDTO dto) throws SQLException {
|
||||
return dto.updateRow(this);
|
||||
}
|
||||
|
||||
public int updateRows(Collection<UpdateableDTO> dtos) throws SQLException {
|
||||
int count = 0;
|
||||
if (dtos != null)
|
||||
for (UpdateableDTO dto : dtos)
|
||||
count += dto.updateRow(this);
|
||||
return count;
|
||||
}
|
||||
|
||||
public int updateRows(UpdateableDTO[] dtos) throws SQLException {
|
||||
return updateRows(Arrays.asList(dtos));
|
||||
}
|
||||
|
||||
public int insertRows(UpdateableDTO dto) throws SQLException {
|
||||
return dto.insertRow(this);
|
||||
}
|
||||
|
||||
public int insertRows(Collection<UpdateableDTO> dtos) throws SQLException {
|
||||
int count = 0;
|
||||
if (dtos != null)
|
||||
for (UpdateableDTO dto : dtos)
|
||||
count += dto.insertRow(this);
|
||||
return count;
|
||||
}
|
||||
|
||||
public int insertRows(UpdateableDTO[] dtos) throws SQLException {
|
||||
return insertRows(Arrays.asList(dtos));
|
||||
}
|
||||
|
||||
// these grab ResultSets from the database
|
||||
|
||||
public ResultSet toResultSet(PreparedStatement ps, final Object... bindObjects) throws SQLException {
|
||||
return toResultSet(ps, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, bindObjects);
|
||||
}
|
||||
|
||||
public ResultSet toResultSet(PreparedStatement ps, int rsType, int rsConcurrency, final Object... bindObjects) throws SQLException {
|
||||
return bindExecute(ps, bindObjects);
|
||||
}
|
||||
|
||||
public ResultSet toResultSet(String sql, final Object... bindObjects) throws SQLException {
|
||||
return toResultSet(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, bindObjects);
|
||||
}
|
||||
|
||||
public ResultSet toResultSet(String sql, Integer rsType, Integer rsConcurrency, final Object... bindObjects) throws SQLException {
|
||||
//throw new UnsupportedOperationException("Can't return ResultSet from String because the PreparedStatement can't be closed before the ResultSet is, so CachingQueryMapper will work.");
|
||||
// works with StatementClosingResultSet
|
||||
boolean error = true;
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql, rsType.intValue(), rsConcurrency.intValue());
|
||||
rs = this.toResultSet(ps, bindObjects);
|
||||
error = false;
|
||||
return new StatementClosingResultSet(rs, ps);
|
||||
} finally {
|
||||
if (error) {
|
||||
tryClose(rs);
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// these are standard getters
|
||||
|
||||
public ResultSetMapper getCustomResultSetMapper() {
|
||||
return cm;
|
||||
}
|
||||
|
||||
public Connection getConnection() {
|
||||
return conn;
|
||||
}
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||
|
||||
public <T> T toObject(PreparedStatement ps, Class<T> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toObject(bindExecute(ps, bindObjects), componentType);
|
||||
}
|
||||
|
||||
public <T> T toObject(String sql, Class<T> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toObject(ps, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(PreparedStatement ps, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toSingleMap(bindExecute(ps, bindObjects), componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(String sql, Class<T> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toSingleMap(ps, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <V> Map<String, V> toSingleMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toSingleMap(bindExecute(ps, bindObjects), mapValType);
|
||||
}
|
||||
|
||||
public <V> Map<String, V> toSingleMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toSingleMap(ps, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement ps, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toCollection(bindExecute(ps, bindObjects), collectionType, componentType);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, final Class<T> collectionType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toCollection(ps, collectionType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(PreparedStatement ps, T list, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toCollection(bindExecute(ps, bindObjects), list, componentType);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(String sql, T list, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toCollection(ps, list, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMap(bindExecute(ps, bindObjects), map, mapKeyType, componentType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMap(ps, map, mapKeyType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapCollection(bindExecute(ps, bindObjects), returnType, mapKeyType, collectionType, componentType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapCollection(ps, returnType, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapCollection(bindExecute(ps, bindObjects), map, mapKeyType, collectionType, componentType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(String sql, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapCollection(ps, map, mapKeyType, collectionType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return cm.toListIterator(bindExecute(ps, bindObjects), type);
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toListIterator(ps, type, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return cm.toIterator(bindExecute(ps, bindObjects), type);
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toIterator(ps, type, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T[] toArray(PreparedStatement ps, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
return cm.toArray(bindExecute(ps, bindObjects), type);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(String sql, final Class<T> type, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toArray(ps, type, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <E> List<E> toList(PreparedStatement ps, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toList(bindExecute(ps, bindObjects), componentType);
|
||||
}
|
||||
|
||||
public <E> List<E> toList(String sql, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toList(ps, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, E> Map<K, E> toMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMap(bindExecute(ps, bindObjects), mapKeyType, componentType);
|
||||
}
|
||||
|
||||
public <K, E> Map<K, E> toMap(String sql, Class<K> mapKeyType, Class<E> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMap(ps, mapKeyType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(PreparedStatement ps, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapList(bindExecute(ps, bindObjects), mapKeyType, componentType);
|
||||
}
|
||||
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(String sql, Class<K> mapKeyType, Class<C> componentType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapList(ps, mapKeyType, componentType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement ps, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toCollectionMap(bindExecute(ps, bindObjects), collectionType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toCollectionMap(ps, collectionType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(PreparedStatement ps, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toCollectionMap(bindExecute(ps, bindObjects), list, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(String sql, T list, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toCollectionMap(ps, list, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapMap(bindExecute(ps, bindObjects), returnType, mapKeyType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapMap(ps, returnType, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapMap(bindExecute(ps, bindObjects), map, mapKeyType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(String sql, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapMap(ps, map, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement ps, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapCollectionMap(bindExecute(ps, bindObjects), returnType, mapKeyType, collectionType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapCollectionMap(ps, returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(PreparedStatement ps, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapCollectionMap(bindExecute(ps, bindObjects), map, mapKeyType, collectionType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(String sql, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapCollectionMap(ps, map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toListIteratorMap(bindExecute(ps, bindObjects), type, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toListIteratorMap(ps, type, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toIteratorMap(bindExecute(ps, bindObjects), type, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toIteratorMap(ps, type, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(PreparedStatement ps, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toArrayMap(bindExecute(ps, bindObjects), type, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(String sql, final Class<T> type, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toArrayMap(ps, type, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(PreparedStatement ps, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toListMap(bindExecute(ps, bindObjects), componentType, mapValType);
|
||||
}
|
||||
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(String sql, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toListMap(ps, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapMap(bindExecute(ps, bindObjects), mapKeyType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapMap(ps, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement ps, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapListMap(bindExecute(ps, bindObjects), mapKeyType, componentType, mapValType);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapListMap(ps, mapKeyType, componentType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toListIteratorMap(bindExecute(ps, bindObjects), mapValType);
|
||||
}
|
||||
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toListIteratorMap(ps, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toIteratorMap(bindExecute(ps, bindObjects), mapValType);
|
||||
}
|
||||
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toIteratorMap(ps, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <V> List<Map<String, V>> toListMap(PreparedStatement ps, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toListMap(bindExecute(ps, bindObjects), mapValType);
|
||||
}
|
||||
|
||||
public <V> List<Map<String, V>> toListMap(String sql, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toListMap(ps, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(PreparedStatement ps, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapMap(bindExecute(ps, bindObjects), mapKeyType, mapValType);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapMap(ps, mapKeyType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(PreparedStatement ps, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
return cm.toMapListMap(bindExecute(ps, bindObjects), mapKeyType, mapValType);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(String sql, Class<K> mapKeyType, Class<V> mapValType, final Object... bindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sql);
|
||||
return this.toMapListMap(ps, mapKeyType, mapValType, bindObjects);
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,955 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.*;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Default ResultSetMapper implementation for Objects.
|
||||
* <p/>
|
||||
* This class is heavily modified from org.apache.beehive.controls.system.jdbc.DefaultObjectResultSetMapper
|
||||
* <p/>
|
||||
* This uses CustomRowToObjectMapper to perform the actual mapping to individual classes, so look to that
|
||||
* implementation for details.
|
||||
* <p/>
|
||||
* This supports mapping to a single object, or collections of Objects, currently it supports:
|
||||
* 1. arrays
|
||||
* 2. anything implementing java.util.Collection with a public no-arg constructor
|
||||
* 3. anything implementing java.util.Map with a public no-arg constructor
|
||||
* a. The first column in the ResultSet will be the Map's key
|
||||
* b. If there are only two columns, the second will be the Map's value
|
||||
* c. If there are more than two columns, the value will be mapped to an object with the entire ResultSet in it,
|
||||
* including the key, just like returning a Collection would do
|
||||
* 4. Iterators returned by a Collection, or ListIterators returned by a List
|
||||
* <p/>
|
||||
* It has sensible default implementations to return if you specify an interface, look in Map 'interfaceToConcrete'
|
||||
* for the default values returned for specific interfaces. If not specified in there, Map's default is HashMap,
|
||||
* while Collection's default is ArrayList.
|
||||
* <p/>
|
||||
* Anything else must be a concrete class with a public no-arg constructor to instantiate it
|
||||
*
|
||||
* @author Travis Burtrum (modifications from beehive)
|
||||
*/
|
||||
public class ResultSetMapper implements RowMapperProvider {
|
||||
|
||||
public static final Map<Class, Class> interfaceToConcrete = Collections.unmodifiableMap(new HashMap<Class, Class>() {{
|
||||
// Collection's
|
||||
put(Collection.class, ArrayList.class);
|
||||
// List
|
||||
put(List.class, ArrayList.class);
|
||||
// Set's
|
||||
put(Set.class, HashSet.class);
|
||||
// SortedSet's
|
||||
put(SortedSet.class, TreeSet.class);
|
||||
put(NavigableSet.class, ConcurrentSkipListSet.class);
|
||||
// Queue's
|
||||
put(Queue.class, LinkedList.class);
|
||||
put(Deque.class, LinkedList.class);
|
||||
// BlockingQueue's
|
||||
put(BlockingQueue.class, LinkedBlockingQueue.class);
|
||||
put(BlockingDeque.class, LinkedBlockingDeque.class);
|
||||
|
||||
// Map's
|
||||
put(Map.class, HashMap.class);
|
||||
// ConcurrentMap's
|
||||
put(ConcurrentMap.class, ConcurrentHashMap.class);
|
||||
put(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class);
|
||||
// SortedMap's
|
||||
put(SortedMap.class, TreeMap.class);
|
||||
put(NavigableMap.class, TreeMap.class);
|
||||
}});
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static <T, E> Class<? extends T> getConcreteClass(final Class<T> returnType, final Class<E> defaultConcreteClass) {
|
||||
int classModifiers = returnType.getModifiers();
|
||||
if (Modifier.isInterface(classModifiers) || Modifier.isAbstract(classModifiers)) {
|
||||
Class<? extends T> concrete = (Class<? extends T>) interfaceToConcrete.get(returnType);
|
||||
return concrete == null ? (Class<? extends T>) defaultConcreteClass : concrete;
|
||||
}
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public static <T, E> T instantiateClass(final Class<T> returnType, final Class<E> defaultConcreteClass) {
|
||||
try {
|
||||
return getConcreteClass(returnType, defaultConcreteClass).newInstance();
|
||||
} catch (Throwable e) {
|
||||
throw new MapperException("Failed to instantiate class of type " + returnType.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private final Calendar cal;
|
||||
private final int arrayMaxLength;
|
||||
|
||||
public ResultSetMapper(Calendar cal, int arrayMaxLength) {
|
||||
this.cal = cal;
|
||||
this.arrayMaxLength = arrayMaxLength;
|
||||
}
|
||||
|
||||
public ResultSetMapper() {
|
||||
this(-1);
|
||||
}
|
||||
|
||||
public ResultSetMapper(int arrayMaxLength) {
|
||||
this(null, arrayMaxLength);
|
||||
}
|
||||
|
||||
protected <T> T privToObject(ResultSet rs, Class<T> componentType, Calendar cal, Class<?> mapValType) {
|
||||
T ret = null;
|
||||
try {
|
||||
if (rs.next())
|
||||
ret = getRowMapper(rs, componentType, cal, mapValType, null).mapRowToReturnType();
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
tryClose(rs);
|
||||
return ret == null ? RowToObjectMapper.fixNull(componentType) : ret;
|
||||
}
|
||||
|
||||
protected <T extends Collection<E>, E> T privToCollection(ResultSet rs, final Class<T> collectionType, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToCollection(rs, instantiateClass(collectionType, ArrayList.class), componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the return type of the method is an array type.
|
||||
*
|
||||
* @param rs ResultSet to process.
|
||||
* @param componentType The class of object contained within the array
|
||||
* @param arrayMaxLength The maximum size of array to create, a value of 0 indicates that the array
|
||||
* size will be the same as the result set size (no limit).
|
||||
* @param cal A calendar instance to use for date/time values
|
||||
* @return An array of the specified class type
|
||||
*/
|
||||
protected <T extends Collection<E>, E> T privToCollection(ResultSet rs, T list, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
int numRows = 0;
|
||||
// dereference list in an attempt to gracefully avoid OutOfMemoryError's
|
||||
final SoftReference<T> softList = new SoftReference<T>(list);
|
||||
list = null;
|
||||
try {
|
||||
// a value of less than 1 indicates that all rows from the ResultSet should be included.
|
||||
final boolean unlimitedRows = arrayMaxLength < 1;
|
||||
|
||||
final RowMapper<?, E> rowMapper = getRowMapper(rs, componentType, cal, mapValType, null);
|
||||
|
||||
for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) {
|
||||
E object = rowMapper.mapRowToReturnType();
|
||||
|
||||
list = softList.get();
|
||||
if (list == null)
|
||||
throw new OutOfMemoryError();
|
||||
list.add(object);
|
||||
list = null;
|
||||
}
|
||||
|
||||
if (!unlimitedRows)
|
||||
warnOnMaxLength(numRows, arrayMaxLength, rs);
|
||||
|
||||
list = softList.get();
|
||||
if (list == null)
|
||||
throw new OutOfMemoryError();
|
||||
|
||||
// if this list is Finishable, call finish()
|
||||
if (list instanceof Finishable)
|
||||
((Finishable) list).finish(rs);
|
||||
|
||||
tryClose(rs);
|
||||
return list;
|
||||
} catch(OutOfMemoryError e){
|
||||
tryClose(rs);
|
||||
throw new MapperException(String.format("Too many rows (processed %d, max %d), ran out of memory.", numRows, arrayMaxLength), e);
|
||||
} catch(Throwable e) {
|
||||
if(list == null)
|
||||
list = softList.get();
|
||||
String columnName = "UNKNOWN";
|
||||
String columnType = "UNKNOWN";
|
||||
String returnedType = "UNKNOWN";
|
||||
int badColumn = 0;
|
||||
try {
|
||||
ResultSetMetaData md = rs.getMetaData();
|
||||
badColumn = e.getCause() instanceof SQLExceptionColumnNum ? ((SQLExceptionColumnNum)e.getCause()).getColumnNum() : 1;
|
||||
columnName = md.getColumnLabel(badColumn);
|
||||
columnType = md.getColumnTypeName(badColumn);
|
||||
returnedType = ((list != null && !list.isEmpty()) ? list.iterator().next() : rs.getObject(badColumn)).getClass().getName();
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
tryClose(rs);
|
||||
// assuming no errors in resultSetObject() this can only happen
|
||||
// for single column result sets.
|
||||
throw new MapperException("The declared Java type for "
|
||||
+ String.format("%s<%s>"
|
||||
, (list != null ? list.getClass() : "UnknownCollection")
|
||||
, getComponentName(componentType, mapValType))
|
||||
+ " is incompatible with the SQL format of column " + badColumn + " '" + columnName
|
||||
+ "' (" + columnType + ") which returns objects of type " + returnedType,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends Map<K, E>, K, E> T privToMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToMap(rs, instantiateClass(returnType, HashMap.class), mapKeyType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the return type of the method is a Map type.
|
||||
*
|
||||
* @param rs ResultSet to process.
|
||||
* @param arrayMaxLength The maximum size of array to create, a value of 0 indicates that the array
|
||||
* size will be the same as the result set size (no limit).
|
||||
* @param cal A calendar instance to use for date/time values
|
||||
* @return An array of the specified class type
|
||||
*/
|
||||
protected <T extends Map<K, E>, K, E> T privToMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
int numRows = 0;
|
||||
// dereference map in an attempt to gracefully avoid OutOfMemoryError's
|
||||
final SoftReference<T> softMap = new SoftReference<T>(map);
|
||||
map = null;
|
||||
try {
|
||||
// a value of less than 1 indicates that all rows from the ResultSet should be included.
|
||||
final boolean unlimitedRows = arrayMaxLength < 1;
|
||||
|
||||
final RowMapper<K, E> rowMapper = getRowMapper(rs, componentType, cal, mapValType, mapKeyType);
|
||||
|
||||
for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) {
|
||||
K key = rowMapper.getMapKey();
|
||||
E value = rowMapper.mapRowToReturnType();
|
||||
|
||||
map = softMap.get();
|
||||
if (map == null)
|
||||
throw new OutOfMemoryError();
|
||||
map.put(key, value);
|
||||
map = null;
|
||||
}
|
||||
|
||||
if (!unlimitedRows)
|
||||
warnOnMaxLength(numRows, arrayMaxLength, rs);
|
||||
|
||||
map = softMap.get();
|
||||
if (map == null)
|
||||
throw new OutOfMemoryError();
|
||||
|
||||
// if this map is Finishable, call finish()
|
||||
if (map instanceof Finishable)
|
||||
((Finishable) map).finish(rs);
|
||||
|
||||
tryClose(rs);
|
||||
return map;
|
||||
} catch(OutOfMemoryError e){
|
||||
tryClose(rs);
|
||||
throw new MapperException(String.format("Too many rows (processed %d, max %d), ran out of memory.", numRows, arrayMaxLength), e);
|
||||
}catch (Throwable e) {
|
||||
if(map == null)
|
||||
map = softMap.get();
|
||||
String columnName = "UNKNOWN";
|
||||
String columnType = "UNKNOWN";
|
||||
String returnedType = "UNKNOWN";
|
||||
int badColumn = 0;
|
||||
try {
|
||||
ResultSetMetaData md = rs.getMetaData();
|
||||
badColumn = e.getCause() instanceof SQLExceptionColumnNum ? ((SQLExceptionColumnNum)e.getCause()).getColumnNum() : 1;
|
||||
columnName = md.getColumnLabel(badColumn);
|
||||
columnType = md.getColumnTypeName(badColumn);
|
||||
returnedType = ((map != null && !map.isEmpty()) ? map.values().iterator().next() : rs.getObject(badColumn)).getClass().getName();
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
tryClose(rs);
|
||||
// assuming no errors in resultSetObject() this can only happen
|
||||
// for single column result sets.
|
||||
throw new MapperException("The declared Java type for "
|
||||
+ String.format("%s<%s, %s>"
|
||||
, (map != null ? map.getClass() : "UnknownMap")
|
||||
, mapKeyType != null ? mapKeyType.getName() : "UNKNOWN"
|
||||
, getComponentName(componentType, mapValType))
|
||||
+ " is incompatible with the SQL format of column "+ badColumn + " '" + columnName
|
||||
+ "' (" + columnType + ") which returns objects of type " + returnedType,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends Map<K, E>, K, E extends Collection<C>, C> T privToMapCollection(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToMapCollection(rs, instantiateClass(returnType, HashMap.class), mapKeyType, collectionType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the return type of the method is a Map type with a list for a value.
|
||||
*
|
||||
* @param rs ResultSet to process.
|
||||
* @param arrayMaxLength The maximum size of array to create, a value of 0 indicates that the array
|
||||
* size will be the same as the result set size (no limit).
|
||||
* @param cal A calendar instance to use for date/time values
|
||||
* @return An array of the specified class type
|
||||
*/
|
||||
protected <T extends Map<K, E>, K, E extends Collection<C>, C> T privToMapCollection(ResultSet rs, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
int numRows = 0;
|
||||
// dereference map in an attempt to gracefully avoid OutOfMemoryError's
|
||||
final SoftReference<T> softMap = new SoftReference<T>(map);
|
||||
map = null;
|
||||
try {
|
||||
// a value of less than 1 indicates that all rows from the ResultSet should be included.
|
||||
final boolean unlimitedRows = arrayMaxLength < 1;
|
||||
|
||||
final RowMapper<K, C> rowMapper = getRowMapper(rs, componentType, cal, mapValType, mapKeyType);
|
||||
|
||||
for (; (unlimitedRows || numRows != arrayMaxLength) && rs.next(); ++numRows) {
|
||||
K key = rowMapper.getMapKey();
|
||||
C value = rowMapper.mapRowToReturnType();
|
||||
|
||||
map = softMap.get();
|
||||
if (map == null)
|
||||
throw new OutOfMemoryError();
|
||||
E list = map.get(key);
|
||||
if(list == null){
|
||||
list = instantiateClass(collectionType, ArrayList.class);
|
||||
map.put(key, list);
|
||||
}
|
||||
list.add(value);
|
||||
map = null;
|
||||
}
|
||||
|
||||
if (!unlimitedRows)
|
||||
warnOnMaxLength(numRows, arrayMaxLength, rs);
|
||||
|
||||
map = softMap.get();
|
||||
if (map == null)
|
||||
throw new OutOfMemoryError();
|
||||
|
||||
// if this map is Finishable, call finish()
|
||||
if (map instanceof Finishable)
|
||||
((Finishable) map).finish(rs);
|
||||
|
||||
tryClose(rs);
|
||||
return map;
|
||||
} catch(OutOfMemoryError e){
|
||||
tryClose(rs);
|
||||
throw new MapperException(String.format("Too many rows (processed %d, max %d), ran out of memory.", numRows, arrayMaxLength), e);
|
||||
}catch (Throwable e) {
|
||||
if(map == null)
|
||||
map = softMap.get();
|
||||
String columnName = "UNKNOWN";
|
||||
String columnType = "UNKNOWN";
|
||||
String returnedType = "UNKNOWN";
|
||||
int badColumn = 0;
|
||||
try {
|
||||
ResultSetMetaData md = rs.getMetaData();
|
||||
badColumn = e.getCause() instanceof SQLExceptionColumnNum ? ((SQLExceptionColumnNum)e.getCause()).getColumnNum() : 1;
|
||||
columnName = md.getColumnLabel(badColumn);
|
||||
columnType = md.getColumnTypeName(badColumn);
|
||||
returnedType = ((map != null && !map.isEmpty()) ? map.values().iterator().next() : rs.getObject(badColumn)).getClass().getName();
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
tryClose(rs);
|
||||
// assuming no errors in resultSetObject() this can only happen
|
||||
// for single column result sets.
|
||||
throw new MapperException("The declared Java type for "
|
||||
+ String.format("%s<%s, %s>"
|
||||
, (map != null ? map.getClass() : "UnknownMap")
|
||||
, mapKeyType != null ? mapKeyType.getName() : "UNKNOWN"
|
||||
, getComponentName(componentType, mapValType))
|
||||
+ " is incompatible with the SQL format of column "+ badColumn + " '" + columnName
|
||||
+ "' (" + columnType + ") which returns objects of type " + returnedType,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// methods using toMapCollection to return different types
|
||||
protected <T> ListIterator<T> privToListIterator(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToList(rs, type, arrayMaxLength, cal, mapValType).listIterator();
|
||||
}
|
||||
|
||||
protected <T> Iterator<T> privToIterator(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToList(rs, type, arrayMaxLength, cal, mapValType).iterator();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected <T> T[] privToArray(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
List<T> list = privToList(rs, type, arrayMaxLength, cal, mapValType);
|
||||
return list.toArray((T[]) Array.newInstance(type, list.size()));
|
||||
}
|
||||
|
||||
protected <E> List<E> privToList(ResultSet rs, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToCollection(rs, new ArrayList<E>(), componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
protected <K, E> Map<K, E> privToMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToMap(rs, new HashMap<K, E>(), mapKeyType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
protected <K, E extends Collection<C>, C> Map<K, E> privToMapCollection(ResultSet rs, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength, Calendar cal, Class<?> mapValType) {
|
||||
return privToMapCollection(rs, new HashMap<K, E>(), mapKeyType, collectionType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
// fairly un-interesting methods below here
|
||||
public <K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new RowToObjectMapper<K, T>(resultSet, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
|
||||
protected void warnOnMaxLength(final int numRows, final int arrayMaxLength, final ResultSet rs) {
|
||||
if (numRows < arrayMaxLength)
|
||||
return;
|
||||
int totalRows = numRows;
|
||||
try {
|
||||
if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
|
||||
rs.last();
|
||||
totalRows = rs.getRow();
|
||||
} else {
|
||||
totalRows = rs.getRow();
|
||||
while (rs.next())
|
||||
++totalRows;
|
||||
}
|
||||
if (totalRows == 0)
|
||||
totalRows = numRows;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.err.printf("This JdbcControl query returned %d rows, %s arrayMaxLength (%d), which you most likely never want to happen, investigate!!!!\n",
|
||||
totalRows, totalRows == numRows ? "equaling" : "exceeding", arrayMaxLength);
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
// overloaded helper methods
|
||||
|
||||
public <T> T toObject(ResultSet rs, Class<T> componentType, Calendar cal) {
|
||||
return privToObject(rs, componentType, cal, null);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, final Class<T> collectionType, Class<E> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToCollection(rs, collectionType, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, T list, Class<E> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToCollection(rs, list, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMap(rs, map, mapKeyType, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMapCollection(rs, returnType, mapKeyType, collectionType, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMapCollection(rs, map, mapKeyType, collectionType, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal) {
|
||||
return privToListIterator(rs, type, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal) {
|
||||
return privToIterator(rs, type, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(ResultSet rs, final Class<T> type, int arrayMaxLength, Calendar cal) {
|
||||
return privToArray(rs, type, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple List of componentType
|
||||
*/
|
||||
public <E> List<E> toList(ResultSet rs, Class<E> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToList(rs, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple Map of mapKeyType -> componentType
|
||||
*/
|
||||
public <K, E> Map<K, E> toMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMap(rs, mapKeyType, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple Map of mapKeyType -> List<componentType>
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(ResultSet rs, Class<K> mapKeyType, Class<C> componentType, int arrayMaxLength, Calendar cal) {
|
||||
return (Map<K, E>) privToMapCollection(rs, mapKeyType, List.class, componentType, arrayMaxLength, cal, null);
|
||||
}
|
||||
|
||||
// map methods
|
||||
|
||||
// the following 6 methods I can find no way to not require an unchecked cast on the object being returned
|
||||
// please find a way and let me know, until then, I won't provide overloaded methods for them
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToCollection(rs, collectionType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, T list, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToCollection(rs, list, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMap(rs, returnType, mapKeyType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMap(rs, map, mapKeyType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMapCollection(rs, returnType, mapKeyType, collectionType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToMapCollection(rs, map, mapKeyType, collectionType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(ResultSet rs, Class<T> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return privToObject(rs, componentType, cal, mapValType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return (ListIterator<Map<String, V>>) privToListIterator(rs, type, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return (Iterator<Map<String, V>>) privToIterator(rs, type, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return privToArray(rs, type, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(ResultSet rs, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return (List<Map<String, V>>) privToList(rs, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return (Map<K, Map<String, V>>) privToMap(rs, mapKeyType, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return (Map<K, List<Map<String, V>>>) privToMapCollection(rs, mapKeyType, List.class, componentType, arrayMaxLength, cal, mapValType);
|
||||
}
|
||||
|
||||
// overloaded map methods that don't require you to specify the type of map you want
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <V> Map<String, V> toSingleMap(ResultSet rs, Class<V> mapValType, Calendar cal) {
|
||||
return toSingleMap(rs, Map.class, mapValType, cal);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return toListIteratorMap(rs, Map.class, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return toIteratorMap(rs, Map.class, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <V> List<Map<String, V>> toListMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return toListMap(rs, Map.class, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return toMapMap(rs, mapKeyType, Map.class, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, int arrayMaxLength, Calendar cal) {
|
||||
return this.toMapListMap(rs, mapKeyType, Map.class, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
// completely useless except inside this class
|
||||
|
||||
private static String getComponentName(Class<?> componentType, Class<?> mapValType){
|
||||
final String componentName = componentType != null ? componentType.getName() : "UNKNOWN";
|
||||
if(Map.class.isAssignableFrom(componentType))
|
||||
return String.format("%s<java.lang.String, %s>",
|
||||
componentName, mapValType != null ? mapValType.getName() : "java.lang.Object");
|
||||
if(componentType != null && componentType.isArray())
|
||||
return componentType.getComponentType().getName()+"[]";
|
||||
return componentName;
|
||||
}
|
||||
|
||||
protected void tryClose(ResultSet rs) {
|
||||
//todo: if (canCloseResultSet())
|
||||
TryClose.tryClose(rs);
|
||||
}
|
||||
|
||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||
|
||||
public <T> T toObject(ResultSet rs, Class<T> componentType) {
|
||||
return this.toObject(rs, componentType, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V> toSingleMap(ResultSet rs, Class<T> componentType, Class<V> mapValType) {
|
||||
return this.toSingleMap(rs, componentType, mapValType, cal);
|
||||
}
|
||||
|
||||
public <V> Map<String, V> toSingleMap(ResultSet rs, Class<V> mapValType) {
|
||||
return this.toSingleMap(rs, mapValType, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, final Class<T> collectionType, Class<E> componentType) {
|
||||
return this.toCollection(rs, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, final Class<T> collectionType, Class<E> componentType, int arrayMaxLength) {
|
||||
return this.toCollection(rs, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, final Class<T> collectionType, Class<E> componentType, Calendar cal) {
|
||||
return this.toCollection(rs, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, T list, Class<E> componentType) {
|
||||
return this.toCollection(rs, list, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, T list, Class<E> componentType, int arrayMaxLength) {
|
||||
return this.toCollection(rs, list, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> T toCollection(ResultSet rs, T list, Class<E> componentType, Calendar cal) {
|
||||
return this.toCollection(rs, list, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType) {
|
||||
return this.toMap(rs, map, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength) {
|
||||
return this.toMap(rs, map, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E> T toMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, Calendar cal) {
|
||||
return this.toMap(rs, map, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType) {
|
||||
return this.toMapCollection(rs, returnType, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength) {
|
||||
return this.toMapCollection(rs, returnType, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, Calendar cal) {
|
||||
return this.toMapCollection(rs, returnType, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType) {
|
||||
return this.toMapCollection(rs, map, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, int arrayMaxLength) {
|
||||
return this.toMapCollection(rs, map, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> T toMapCollection(ResultSet rs, T map, Class<K> mapKeyType, Class<E> collectionType, Class<C> componentType, Calendar cal) {
|
||||
return this.toMapCollection(rs, map, mapKeyType, collectionType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(ResultSet rs, final Class<T> type) {
|
||||
return this.toListIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(ResultSet rs, final Class<T> type, int arrayMaxLength) {
|
||||
return this.toListIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> ListIterator<T> toListIterator(ResultSet rs, final Class<T> type, Calendar cal) {
|
||||
return this.toListIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(ResultSet rs, final Class<T> type) {
|
||||
return this.toIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(ResultSet rs, final Class<T> type, int arrayMaxLength) {
|
||||
return this.toIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> Iterator<T> toIterator(ResultSet rs, final Class<T> type, Calendar cal) {
|
||||
return this.toIterator(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(ResultSet rs, final Class<T> type) {
|
||||
return this.toArray(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(ResultSet rs, final Class<T> type, int arrayMaxLength) {
|
||||
return this.toArray(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T> T[] toArray(ResultSet rs, final Class<T> type, Calendar cal) {
|
||||
return this.toArray(rs, type, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E> List<E> toList(ResultSet rs, Class<E> componentType) {
|
||||
return this.toList(rs, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E> List<E> toList(ResultSet rs, Class<E> componentType, int arrayMaxLength) {
|
||||
return this.toList(rs, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E> List<E> toList(ResultSet rs, Class<E> componentType, Calendar cal) {
|
||||
return this.toList(rs, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E> Map<K, E> toMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType) {
|
||||
return this.toMap(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E> Map<K, E> toMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, int arrayMaxLength) {
|
||||
return this.toMap(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E> Map<K, E> toMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Calendar cal) {
|
||||
return this.toMap(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(ResultSet rs, Class<K> mapKeyType, Class<C> componentType) {
|
||||
return this.toMapList(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(ResultSet rs, Class<K> mapKeyType, Class<C> componentType, int arrayMaxLength) {
|
||||
return this.toMapList(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends List<C>, C> Map<K, E> toMapList(ResultSet rs, Class<K> mapKeyType, Class<C> componentType, Calendar cal) {
|
||||
return this.toMapList(rs, mapKeyType, componentType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toCollectionMap(rs, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toCollectionMap(rs, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, final Class<T> collectionType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toCollectionMap(rs, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, T list, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toCollectionMap(rs, list, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, T list, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toCollectionMap(rs, list, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E extends Map<String, V>, V> T toCollectionMap(ResultSet rs, T list, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toCollectionMap(rs, list, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapMap(rs, returnType, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapMap(rs, returnType, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapMap(rs, returnType, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapMap(rs, map, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapMap(rs, map, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, E>, K, E extends Map<String, V>, V> T toMapMap(ResultSet rs, T map, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapMap(rs, map, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapCollectionMap(rs, returnType, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapCollectionMap(rs, returnType, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, final Class<T> returnType, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapCollectionMap(rs, returnType, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapCollectionMap(rs, map, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapCollectionMap(rs, map, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<K, C>, K, C extends Collection<E>, E extends Map<String, V>, V> T toMapCollectionMap(ResultSet rs, T map, Class<K> mapKeyType, Class<C> collectionType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapCollectionMap(rs, map, mapKeyType, collectionType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType) {
|
||||
return this.toListIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toListIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, Calendar cal) {
|
||||
return this.toListIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType) {
|
||||
return this.toIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, final Class<T> type, Class<V> mapValType, Calendar cal) {
|
||||
return this.toIteratorMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(ResultSet rs, final Class<T> type, Class<V> mapValType) {
|
||||
return this.toArrayMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(ResultSet rs, final Class<T> type, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toArrayMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <T extends Map<String, V>, V> Map<String, V>[] toArrayMap(ResultSet rs, final Class<T> type, Class<V> mapValType, Calendar cal) {
|
||||
return this.toArrayMap(rs, type, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(ResultSet rs, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toListMap(rs, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(ResultSet rs, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toListMap(rs, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <E extends Map<String, V>, V> List<Map<String, V>> toListMap(ResultSet rs, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toListMap(rs, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType) {
|
||||
return this.toMapListMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapListMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, E extends Map<String, V>, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<E> componentType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapListMap(rs, mapKeyType, componentType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, Class<V> mapValType) {
|
||||
return this.toListIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toListIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> ListIterator<Map<String, V>> toListIteratorMap(ResultSet rs, Class<V> mapValType, Calendar cal) {
|
||||
return this.toListIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, Class<V> mapValType) {
|
||||
return this.toIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> Iterator<Map<String, V>> toIteratorMap(ResultSet rs, Class<V> mapValType, Calendar cal) {
|
||||
return this.toIteratorMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> List<Map<String, V>> toListMap(ResultSet rs, Class<V> mapValType) {
|
||||
return this.toListMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> List<Map<String, V>> toListMap(ResultSet rs, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toListMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <V> List<Map<String, V>> toListMap(ResultSet rs, Class<V> mapValType, Calendar cal) {
|
||||
return this.toListMap(rs, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType) {
|
||||
return this.toMapMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, Map<String, V>> toMapMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType) {
|
||||
return this.toMapListMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, int arrayMaxLength) {
|
||||
return this.toMapListMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
public <K, V> Map<K, List<Map<String, V>>> toMapListMap(ResultSet rs, Class<K> mapKeyType, Class<V> mapValType, Calendar cal) {
|
||||
return this.toMapListMap(rs, mapKeyType, mapValType, arrayMaxLength, cal);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public interface RowMapper<K,T> {
|
||||
/**
|
||||
* Map a ResultSet row to the return type class
|
||||
* @return An instance of class, if _mapKeyType is not null and _columnCount is 2, return only index 2
|
||||
*/
|
||||
T mapRowToReturnType() throws SQLException;
|
||||
|
||||
/**
|
||||
* key for map
|
||||
* @return index number 1, with type of _mapKeyType
|
||||
* @throws MapperException if _mapKeyType is null
|
||||
*/
|
||||
K getMapKey() throws SQLException;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public interface RowMapperProvider {
|
||||
<K, T> RowMapper<K, T> getRowMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType);
|
||||
}
|
@ -1,641 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
|
||||
import com.moparisthebest.jdbc.util.CaseInsensitiveHashMap;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.moparisthebest.jdbc.UpdateableDTO.YES;
|
||||
import static com.moparisthebest.jdbc.UpdateableDTO.NO;
|
||||
|
||||
/**
|
||||
* Map a ResultSet row to an Object. This mapper uses Java reflection to perform the mapping.
|
||||
* <p/>
|
||||
* This class is modified from org.apache.beehive.controls.system.jdbc.RowToObjectMapper
|
||||
* <p/>
|
||||
* The column names are compared, case insensitive, and with and without underscores (_), to the set* methods
|
||||
* and fields of the given class to map the fields. For example:
|
||||
* <p/>
|
||||
* USERID would prefer method setUserId(), and fall back to field userId if the method doesn't exist
|
||||
* USER_ID would act the same as the above, but also additionally try to match method setUser_Id(), or field user_id
|
||||
* <p/>
|
||||
* First, this class will look for a constructor that takes a ResultSet as a parameter, if it finds one, it will
|
||||
* instantiate it with that constructor, sending in the ResultSet. Otherwise, this will only try to use public
|
||||
* setters, but will set fields regardless of specified access, even private fields.
|
||||
*
|
||||
* @author Travis Burtrum (modifications from beehive)
|
||||
*/
|
||||
public class RowToObjectMapper<K, T> extends AbstractRowMapper<K, T> {
|
||||
|
||||
private static final String SETTER_NAME_REGEX = "^(set)([A-Z_]\\w*+)";
|
||||
protected static final TypeMappingsFactory _tmf = TypeMappingsFactory.getInstance();
|
||||
protected static final Pattern _setterRegex = Pattern.compile(SETTER_NAME_REGEX);
|
||||
|
||||
public static final int TYPE_BOOLEAN = _tmf.getTypeId(Boolean.TYPE);//TypeMappingsFactory.TYPE_BOOLEAN; // not public?
|
||||
public static final int TYPE_BOOLEAN_OBJ = _tmf.getTypeId(Boolean.class);//TypeMappingsFactory.TYPE_BOOLEAN_OBJ; // not public?
|
||||
|
||||
protected boolean resultSetConstructor, constructorLoaded = false;
|
||||
protected Constructor<? extends T> constructor;
|
||||
protected final Class<? extends T> _returnTypeClass; // over-ride non-generic version of this in super class
|
||||
|
||||
// only non-null when _returnTypeClass is an array, or a map
|
||||
protected final Class<?> componentType;
|
||||
protected final boolean returnMap;
|
||||
|
||||
protected AccessibleObject[] _fields = null;
|
||||
protected int[] _fieldTypes;
|
||||
|
||||
protected final Object[] _args = new Object[1];
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass) {
|
||||
this(resultSet, returnTypeClass, null, null);
|
||||
}
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Class<?> mapValType) {
|
||||
this(resultSet, returnTypeClass, null, mapValType);
|
||||
}
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal) {
|
||||
this(resultSet, returnTypeClass, cal, null);
|
||||
}
|
||||
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType) {
|
||||
this(resultSet, returnTypeClass, cal, mapValType, null);
|
||||
}
|
||||
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
this(resultSet, returnTypeClass, cal, mapValType, mapKeyType, false);
|
||||
}
|
||||
|
||||
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType, boolean caseInsensitiveMap) {
|
||||
this(null, resultSet, returnTypeClass, cal, mapValType, mapKeyType, caseInsensitiveMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new RowToObjectMapper.
|
||||
*
|
||||
* @param resultSet ResultSet to map
|
||||
* @param returnTypeClass Class to map to.
|
||||
* @param cal Calendar instance for date/time mappings.
|
||||
*/
|
||||
public RowToObjectMapper(String[] keys, ResultSet resultSet, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType, boolean caseInsensitiveMap) {
|
||||
super(keys, resultSet, returnTypeClass, cal, mapKeyType);
|
||||
returnMap = Map.class.isAssignableFrom(returnTypeClass);
|
||||
if(returnMap){
|
||||
Class<? extends T> rtc = ResultSetMapper.getConcreteClass(returnTypeClass, HashMap.class);
|
||||
if(caseInsensitiveMap && HashMap.class.equals(rtc)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Class<? extends T> rtct = (Class<? extends T>) CaseInsensitiveHashMap.class;
|
||||
rtc = rtct;
|
||||
}
|
||||
_returnTypeClass = rtc;
|
||||
componentType = mapValType;
|
||||
}else{
|
||||
_returnTypeClass = returnTypeClass;
|
||||
// detect if we want an array back
|
||||
componentType = returnTypeClass.getComponentType();
|
||||
}
|
||||
}
|
||||
|
||||
protected void lazyLoadConstructor() {
|
||||
if(constructorLoaded)
|
||||
return;
|
||||
// detect if returnTypeClass has a constructor that takes a ResultSet, if so, our job couldn't be easier...
|
||||
boolean resultSetConstructor = false;
|
||||
Constructor<? extends T> constructor = null;
|
||||
try {
|
||||
constructor = _returnTypeClass.getConstructor(ResultSet.class);
|
||||
if (!constructor.isAccessible())
|
||||
constructor.setAccessible(true);
|
||||
resultSetConstructor = true;
|
||||
} catch (Throwable e) {
|
||||
// if no resultSetConstructor find the constructor
|
||||
try {
|
||||
constructor = _returnTypeClass.getDeclaredConstructor();
|
||||
if (!constructor.isAccessible())
|
||||
constructor.setAccessible(true);
|
||||
} catch (Throwable e1) {
|
||||
// if column count is 2 or less, it might map directly to a type like a Long or something, or be a map which does
|
||||
// or if componentType is non-null, then we want an array like Long[] or String[]
|
||||
if(_columnCount > 2 && componentType == null)
|
||||
throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e1);
|
||||
}
|
||||
}
|
||||
this.resultSetConstructor = resultSetConstructor;
|
||||
this.constructor = constructor;
|
||||
this.constructorLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a new instance of the Map class required by Map<String, Object>[]
|
||||
* It lives in it's own method to minimize suppressed warnings and allow subclasses to override methods,
|
||||
* like perhaps to implement the original beehive behavior of case-insensitive strings
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private Map<String, Object> getMapImplementation() throws IllegalAccessException, InstantiationException {
|
||||
return (Map<String, Object>)_returnTypeClass.newInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getMapKey() throws SQLException {
|
||||
return this.extractColumnValue(1, _mapKeyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the mapping.
|
||||
*
|
||||
* @return An object instance.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public T mapRowToReturnType() throws SQLException {
|
||||
|
||||
if(mapOnlySecondColumn)
|
||||
return this.extractColumnValue(2, _returnTypeClass);
|
||||
|
||||
lazyLoadConstructor();
|
||||
|
||||
if (resultSetConstructor)
|
||||
try {
|
||||
return constructor.newInstance(_resultSet);
|
||||
} catch (Throwable e) {
|
||||
throw new MapperException(e.getClass().getName() + " when trying to create instance of : "
|
||||
+ _returnTypeClass.getName() + " sending in a ResultSet object as a parameter", e);
|
||||
}
|
||||
|
||||
if(returnMap) // we want a map
|
||||
try {
|
||||
final Map<String, Object> ret = getMapImplementation();
|
||||
final String[] keys = getKeysFromResultSet();
|
||||
final int columnLength = _columnCount+1;
|
||||
if(componentType != null && componentType != Object.class){ // we want a specific value type
|
||||
int typeId = _tmf.getTypeId(componentType);
|
||||
for(int x = 1; x < columnLength; ++x)
|
||||
ret.put(keys[x].toLowerCase(), extractColumnValue(x, typeId));
|
||||
} else // we want a generic object type
|
||||
for(int x = 1; x < columnLength; ++x)
|
||||
ret.put(keys[x].toLowerCase(), _resultSet.getObject(x));
|
||||
return _returnTypeClass.cast(ret);
|
||||
} 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 {
|
||||
final Object ret = Array.newInstance(componentType, _columnCount);
|
||||
final int typeId = _tmf.getTypeId(componentType);
|
||||
for(int x = 0; x < _columnCount;)
|
||||
Array.set(ret, x, extractColumnValue(++x, typeId));
|
||||
//ret[x] = extractColumnValue(++x, typeId);
|
||||
return _returnTypeClass.cast(ret);
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
T resultObject = null;
|
||||
|
||||
// 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) {
|
||||
return (T)extractColumnValue(1, typeId);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new MapperException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (_fields == null) {
|
||||
try {
|
||||
getFieldMappings();
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
resultObject = constructor.newInstance();
|
||||
} catch (Throwable e) {
|
||||
if(constructor == null) // then this is a different error
|
||||
throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e);
|
||||
throw new MapperException(e.getClass().getName() + " when trying to create instance of : "
|
||||
+ _returnTypeClass.getName(), e);
|
||||
}
|
||||
|
||||
for (int i = 1; i < _fields.length; i++) {
|
||||
AccessibleObject f = _fields[i];
|
||||
|
||||
try {
|
||||
_args[0] = extractColumnValue(i, _fieldTypes[i]);
|
||||
//System.out.printf("field: '%s' obj: '%s' fieldType: '%s'\n", _fields[i], _args[0], _fieldTypes[i]);
|
||||
// custom hacked-in support for enums, can do better when we scrap org.apache.beehive.controls.system.jdbc.TypeMappingsFactory
|
||||
if(_fieldTypes[i] == 0 && _args[0] instanceof String){
|
||||
Class<?> fieldType = f instanceof Field ? ((Field)f).getType() : ((Method)f).getParameterTypes()[0];
|
||||
if(Enum.class.isAssignableFrom(fieldType))
|
||||
_args[0] = Enum.valueOf((Class<? extends Enum>)fieldType, (String)_args[0]);
|
||||
}
|
||||
if (f instanceof Field) {
|
||||
((Field) f).set(resultObject, _args[0]);
|
||||
} else {
|
||||
((Method) f).invoke(resultObject, _args);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException(e.getMessage(), e);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
|
||||
try {
|
||||
ResultSetMetaData md = _resultSet.getMetaData();
|
||||
if (f instanceof Field) {
|
||||
throw new MapperException("The declared Java type for field " + ((Field) f).getName()
|
||||
+ ((Field) f).getType().toString()
|
||||
+ " is incompatible with the SQL format of column " + i + " '" + md.getColumnLabel(i)
|
||||
+ "' (" + md.getColumnTypeName(i)
|
||||
+ ") which returns objects of type " + _args[0].getClass().getName());
|
||||
} else {
|
||||
throw new MapperException("The declared Java type for method " + ((Method) f).getName()
|
||||
+ ((Method) f).getParameterTypes()[0].toString()
|
||||
+ " is incompatible with the SQL format of column " + i + " '" + md.getColumnLabel(i)
|
||||
+ "' (" + md.getColumnTypeName(i)
|
||||
+ ") which returns objects of type " + _args[0].getClass().getName());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
if (f instanceof Field) {
|
||||
throw new MapperException("IllegalAccessException when trying to access field " + ((Field) f).getName(), e);
|
||||
} else {
|
||||
throw new MapperException("IllegalAccessException when trying to access method " + ((Method) f).getName(), e);
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MapperException("InvocationTargetException when trying to access method " + ((Method) f).getName(), e);
|
||||
}
|
||||
}
|
||||
// if this resultObject is Finishable, call finish()
|
||||
if (resultObject instanceof Finishable)
|
||||
try {
|
||||
((Finishable) resultObject).finish(_resultSet);
|
||||
} catch (SQLException e) {
|
||||
throw new MapperException(e.getMessage(), e);
|
||||
}
|
||||
return resultObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided so we can extract a column value to use for the key of a map
|
||||
*
|
||||
* @param index
|
||||
* @param classType
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <E> E extractColumnValue(int index, Class<E> classType) throws SQLException {
|
||||
return classType.cast(extractColumnValue(index, _tmf.getTypeId(classType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the structures necessary to do the mapping
|
||||
*
|
||||
* @throws SQLException on error.
|
||||
*/
|
||||
protected void getFieldMappings()
|
||||
throws SQLException {
|
||||
|
||||
final String[] keys = getKeysFromResultSet();
|
||||
//System.out.println("keys: "+ Arrays.toString(keys));
|
||||
|
||||
// added this to handle stripping '_' from keys
|
||||
Map<String, String> strippedKeys = new HashMap<String, String>();
|
||||
for (final String key : keys) {
|
||||
String strippedKey = key;
|
||||
if (key != null) {
|
||||
strippedKey = key.replaceAll("_", "");
|
||||
if (key.equals(strippedKey))
|
||||
continue;
|
||||
strippedKeys.put(strippedKey, key);
|
||||
}
|
||||
}
|
||||
//System.out.println("strippedKeys: "+strippedKeys);
|
||||
//
|
||||
// find fields or setters for return class
|
||||
//
|
||||
HashMap<String, AccessibleObject> mapFields = new HashMap<String, AccessibleObject>(_columnCount * 2);
|
||||
for (int i = 1; i <= _columnCount; i++) {
|
||||
mapFields.put(keys[i], null);
|
||||
}
|
||||
|
||||
// public methods
|
||||
Method[] classMethods = _returnTypeClass.getMethods();
|
||||
for (Method m : classMethods) {
|
||||
//System.out.printf("method: '%s', isSetterMethod: '%s'\n", m, isSetterMethod(m));
|
||||
if (isSetterMethod(m)) {
|
||||
String fieldName = m.getName().substring(3).toUpperCase();
|
||||
//System.out.println("METHOD-fieldName1: "+fieldName);
|
||||
if (!mapFields.containsKey(fieldName)) {
|
||||
fieldName = strippedKeys.get(fieldName);
|
||||
if (fieldName == null)
|
||||
continue;
|
||||
//System.out.println("METHOD-fieldName2: "+fieldName);
|
||||
}
|
||||
final AccessibleObject field = mapFields.get(fieldName);
|
||||
// check for overloads
|
||||
if (field == null) {
|
||||
mapFields.put(fieldName, m);
|
||||
} else {
|
||||
// fix for 'overloaded' methods when it comes to stripped keys, we want the exact match
|
||||
final String thisName = m.getName().substring(3).toUpperCase();
|
||||
final String previousName = ((Method) field).getName().substring(3).toUpperCase();
|
||||
//System.out.printf("thisName: '%s', previousName: '%s', mapFields.containsKey(thisName): %b, strippedKeys.containsKey(previousName): %b\n", thisName, previousName, mapFields.containsKey(thisName), strippedKeys.containsKey(previousName));
|
||||
if(mapFields.containsKey(thisName) && strippedKeys.containsKey(previousName)) {
|
||||
mapFields.put(fieldName, m);
|
||||
} else if (!mapFields.containsKey(previousName) || !strippedKeys.containsKey(thisName)) {
|
||||
throw new MapperException("Unable to choose between overloaded methods '" + m.getName()
|
||||
+ "' and '" + ((Method) field).getName() + "' for field '" + fieldName + "' on the '" + _returnTypeClass.getName() + "' class. Mapping is done using "
|
||||
+ "a case insensitive comparison of SQL ResultSet columns to field "
|
||||
+ "names and public setter methods on the return class. Columns are also "
|
||||
+ "stripped of '_' and compared if no match is found with them.");
|
||||
}
|
||||
// then the 'overloaded' method is already correct
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix for 8813: include inherited and non-public fields
|
||||
for (Class clazz = _returnTypeClass; clazz != null && clazz != Object.class; clazz = clazz.getSuperclass()) {
|
||||
//System.out.println("searching for fields in class: "+clazz.getName());
|
||||
Field[] classFields = clazz.getDeclaredFields();
|
||||
//System.out.println("fields in class: "+Arrays.toString(classFields));
|
||||
for (Field f : classFields) {
|
||||
if (Modifier.isStatic(f.getModifiers())) continue;
|
||||
//if (!Modifier.isPublic(f.getModifiers())) continue; // commented this out to work on all types of fields
|
||||
String fieldName = f.getName().toUpperCase();
|
||||
//System.out.println("fieldName: "+fieldName);
|
||||
if (!mapFields.containsKey(fieldName)) {
|
||||
fieldName = strippedKeys.get(fieldName);
|
||||
if (fieldName == null)
|
||||
continue;
|
||||
}
|
||||
final AccessibleObject field = mapFields.get(fieldName);
|
||||
if (field == null) {
|
||||
mapFields.put(fieldName, f);
|
||||
} else if(field instanceof Field) {
|
||||
// fix for 'overloaded' fields when it comes to stripped keys, we want the exact match
|
||||
final String thisName = f.getName().toUpperCase();
|
||||
final String previousName = ((Field) field).getName().toUpperCase();
|
||||
//System.out.printf("thisName: '%s', previousName: '%s', mapFields.containsKey(thisName): %b, strippedKeys.containsKey(previousName): %b\n", thisName, previousName, mapFields.containsKey(thisName), strippedKeys.containsKey(previousName));
|
||||
if(mapFields.containsKey(thisName) && strippedKeys.containsKey(previousName)) {
|
||||
mapFields.put(fieldName, f);
|
||||
} else if (!mapFields.containsKey(previousName) || !strippedKeys.containsKey(thisName)) {
|
||||
throw new MapperException("Unable to choose between overloaded fields '" + f.getName()
|
||||
+ "' and '" + ((Field) field).getName() + "' for field '" + fieldName + "' on the '" + _returnTypeClass.getName() + "' class. Mapping is done using "
|
||||
+ "a case insensitive comparison of SQL ResultSet columns to field "
|
||||
+ "names and public setter methods on the return class. Columns are also "
|
||||
+ "stripped of '_' and compared if no match is found with them.");
|
||||
}
|
||||
// then the 'overloaded' field is already correct
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finally actually init the fields array
|
||||
_fields = new AccessibleObject[_columnCount + 1];
|
||||
_fieldTypes = new int[_columnCount + 1];
|
||||
|
||||
for (int i = 1; i < _fields.length; i++) {
|
||||
AccessibleObject f = mapFields.get(keys[i]);
|
||||
if (f == null) {
|
||||
throw new MapperException("Unable to map the SQL column '" + keys[i]
|
||||
+ "' to a field on the '" + _returnTypeClass.getName() +
|
||||
"' class. Mapping is done using a case insensitive comparison of SQL ResultSet "
|
||||
+ "columns to field "
|
||||
+ "names and public setter methods on the return class. Columns are also "
|
||||
+ "stripped of '_' and compared if no match is found with them.");
|
||||
}
|
||||
f.setAccessible(true);
|
||||
_fields[i] = f;
|
||||
if (f instanceof Field) {
|
||||
_fieldTypes[i] = _tmf.getTypeId(((Field) f).getType());
|
||||
} else {
|
||||
_fieldTypes[i] = _tmf.getTypeId(((Method) f).getParameterTypes()[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fixNull(Class<T> returnType) {
|
||||
return returnType.cast(_tmf.fixNull(returnType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method is a java bean setter method.
|
||||
* @param method Method to check
|
||||
* @return True if the method is a setter method.
|
||||
*/
|
||||
protected boolean isSetterMethod(Method method) {
|
||||
Matcher matcher = _setterRegex.matcher(method.getName());
|
||||
if (matcher.matches()) {
|
||||
|
||||
if (Modifier.isStatic(method.getModifiers())) return false;
|
||||
if (!Modifier.isPublic(method.getModifiers())) return false;
|
||||
if (!Void.TYPE.equals(method.getReturnType())) return false;
|
||||
|
||||
// method parameter checks
|
||||
Class[] params = method.getParameterTypes();
|
||||
if (params.length != 1) return false;
|
||||
if (TypeMappingsFactory.TYPE_UNKNOWN == _tmf.getTypeId(params[0])) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
protected Object extractColumnValue(int index, int resultType) throws SQLException {
|
||||
try{
|
||||
switch (resultType) {
|
||||
case TypeMappingsFactory.TYPE_INT:
|
||||
return new Integer(_resultSet.getInt(index));
|
||||
case TypeMappingsFactory.TYPE_LONG:
|
||||
return new Long(_resultSet.getLong(index));
|
||||
case TypeMappingsFactory.TYPE_FLOAT:
|
||||
return new Float(_resultSet.getFloat(index));
|
||||
case TypeMappingsFactory.TYPE_DOUBLE:
|
||||
return new Double(_resultSet.getDouble(index));
|
||||
case TypeMappingsFactory.TYPE_BYTE:
|
||||
return new Byte(_resultSet.getByte(index));
|
||||
case TypeMappingsFactory.TYPE_SHORT:
|
||||
return new Short(_resultSet.getShort(index));
|
||||
case TypeMappingsFactory.TYPE_INT_OBJ:
|
||||
{
|
||||
int i = _resultSet.getInt(index);
|
||||
return _resultSet.wasNull() ? null : new Integer(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_LONG_OBJ:
|
||||
{
|
||||
long i = _resultSet.getLong(index);
|
||||
return _resultSet.wasNull() ? null : new Long(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_FLOAT_OBJ:
|
||||
{
|
||||
float i = _resultSet.getFloat(index);
|
||||
return _resultSet.wasNull() ? null : new Float(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_DOUBLE_OBJ:
|
||||
{
|
||||
double i = _resultSet.getDouble(index);
|
||||
return _resultSet.wasNull() ? null : new Double(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_BYTE_OBJ:
|
||||
{
|
||||
byte i = _resultSet.getByte(index);
|
||||
return _resultSet.wasNull() ? null : new Byte(i);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_SHORT_OBJ:
|
||||
{
|
||||
short i = _resultSet.getShort(index);
|
||||
return _resultSet.wasNull() ? null : new Short(i);
|
||||
}
|
||||
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN:
|
||||
case TypeMappingsFactory.TYPE_BOOLEAN_OBJ:
|
||||
{
|
||||
// do some special handling to convert a database string to a boolean
|
||||
boolean ret;
|
||||
try {
|
||||
// try to get an actual boolean from the database
|
||||
ret = _resultSet.getBoolean(index);
|
||||
// null seems to get returned as false above, so String code won't run if its null
|
||||
if (_resultSet.wasNull())
|
||||
if (resultType == TYPE_BOOLEAN_OBJ)
|
||||
return null; // only return null for Boolean object
|
||||
else
|
||||
throw new MapperException(String.format("Implicit conversion of database string to boolean failed on column '%d'. Returned string needs to be 'Y' or 'N' and was instead 'null'. If you want to accept null values, make it an object Boolean instead of primitive boolean.", index));
|
||||
} catch (SQLException e) {
|
||||
// if we are here, it wasn't a boolean or null, so try to grab a string instead
|
||||
String bool = _resultSet.getString(index);//.toUpperCase(); // do we want it case-insensitive?
|
||||
ret = YES.equals(bool);
|
||||
if (!ret && !NO.equals(bool))
|
||||
throw new MapperException(String.format("Implicit conversion of database string to boolean failed on column '%d'. Returned string needs to be 'Y' or 'N' and was instead '%s'.", index, bool));
|
||||
//throw e;
|
||||
}
|
||||
return ret ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_STRING:
|
||||
case TypeMappingsFactory.TYPE_XMLBEAN_ENUM:
|
||||
return _resultSet.getString(index);
|
||||
case TypeMappingsFactory.TYPE_BIG_DECIMAL:
|
||||
return _resultSet.getBigDecimal(index);
|
||||
case TypeMappingsFactory.TYPE_BYTES:
|
||||
return _resultSet.getBytes(index);
|
||||
case TypeMappingsFactory.TYPE_TIMESTAMP:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getTimestamp(index);
|
||||
else
|
||||
return _resultSet.getTimestamp(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_TIME:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getTime(index);
|
||||
else
|
||||
return _resultSet.getTime(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_SQLDATE:
|
||||
{
|
||||
if (null == _cal)
|
||||
return _resultSet.getDate(index);
|
||||
else
|
||||
return _resultSet.getDate(index, _cal);
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_DATE:
|
||||
{
|
||||
// convert explicity to java.util.Date
|
||||
// 12918 | knex does not return java.sql.Date properly from web service
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_CALENDAR:
|
||||
{
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
Calendar c = (null == _cal) ? Calendar.getInstance() : (Calendar) _cal.clone();
|
||||
c.setTimeInMillis(ts.getTime());
|
||||
return c;
|
||||
}
|
||||
case TypeMappingsFactory.TYPE_REF:
|
||||
return _resultSet.getRef(index);
|
||||
case TypeMappingsFactory.TYPE_BLOB:
|
||||
return _resultSet.getBlob(index);
|
||||
case TypeMappingsFactory.TYPE_CLOB:
|
||||
return _resultSet.getClob(index);
|
||||
case TypeMappingsFactory.TYPE_ARRAY:
|
||||
return _resultSet.getArray(index);
|
||||
case TypeMappingsFactory.TYPE_READER:
|
||||
case TypeMappingsFactory.TYPE_STREAM:
|
||||
throw new MapperException("streaming return types are not supported by the JdbcControl; use ResultSet instead");
|
||||
case TypeMappingsFactory.TYPE_STRUCT:
|
||||
case TypeMappingsFactory.TYPE_UNKNOWN:
|
||||
// JAVA_TYPE (could be any), or REF
|
||||
return _resultSet.getObject(index);
|
||||
default:
|
||||
throw new MapperException("internal error: unknown type ID: " + Integer.toString(resultType));
|
||||
}
|
||||
}catch(SQLException e){
|
||||
throw new SQLExceptionColumnNum(e, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SQLExceptionColumnNum extends SQLException {
|
||||
|
||||
private final int columnNum;
|
||||
|
||||
public SQLExceptionColumnNum(Throwable cause, int columnNum) {
|
||||
super("At column number "+columnNum, cause);
|
||||
this.columnNum = columnNum;
|
||||
}
|
||||
|
||||
public int getColumnNum() {
|
||||
return columnNum;
|
||||
}
|
||||
}
|
@ -1,989 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.sql.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This does exactly what you would expect, delegate to a ResultSet and close a Statement object when you close this ResultSet
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class StatementClosingResultSet implements ResultSet {
|
||||
|
||||
private final ResultSet delegate;
|
||||
private final Statement statement;
|
||||
|
||||
public StatementClosingResultSet(ResultSet delegate, Statement statement) {
|
||||
this.delegate = delegate;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the only method here that doesn't ONLY delegate
|
||||
*
|
||||
* @throws SQLException
|
||||
*/
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
delegate.close();
|
||||
if (statement != null)
|
||||
statement.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next() throws SQLException {
|
||||
return delegate.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasNull() throws SQLException {
|
||||
return delegate.wasNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(int columnIndex) throws SQLException {
|
||||
return delegate.getString(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(int columnIndex) throws SQLException {
|
||||
return delegate.getBoolean(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(int columnIndex) throws SQLException {
|
||||
return delegate.getByte(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(int columnIndex) throws SQLException {
|
||||
return delegate.getShort(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int columnIndex) throws SQLException {
|
||||
return delegate.getInt(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int columnIndex) throws SQLException {
|
||||
return delegate.getLong(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(int columnIndex) throws SQLException {
|
||||
return delegate.getFloat(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int columnIndex) throws SQLException {
|
||||
return delegate.getDouble(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
|
||||
return delegate.getBigDecimal(columnIndex, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(int columnIndex) throws SQLException {
|
||||
return delegate.getBytes(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(int columnIndex) throws SQLException {
|
||||
return delegate.getDate(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(int columnIndex) throws SQLException {
|
||||
return delegate.getTime(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(int columnIndex) throws SQLException {
|
||||
return delegate.getTimestamp(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAsciiStream(int columnIndex) throws SQLException {
|
||||
return delegate.getAsciiStream(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
|
||||
return delegate.getUnicodeStream(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBinaryStream(int columnIndex) throws SQLException {
|
||||
return delegate.getBinaryStream(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String columnLabel) throws SQLException {
|
||||
return delegate.getString(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String columnLabel) throws SQLException {
|
||||
return delegate.getBoolean(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(String columnLabel) throws SQLException {
|
||||
return delegate.getByte(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(String columnLabel) throws SQLException {
|
||||
return delegate.getShort(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String columnLabel) throws SQLException {
|
||||
return delegate.getInt(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(String columnLabel) throws SQLException {
|
||||
return delegate.getLong(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(String columnLabel) throws SQLException {
|
||||
return delegate.getFloat(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String columnLabel) throws SQLException {
|
||||
return delegate.getDouble(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
|
||||
return delegate.getBigDecimal(columnLabel, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(String columnLabel) throws SQLException {
|
||||
return delegate.getBytes(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(String columnLabel) throws SQLException {
|
||||
return delegate.getDate(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(String columnLabel) throws SQLException {
|
||||
return delegate.getTime(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(String columnLabel) throws SQLException {
|
||||
return delegate.getTimestamp(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAsciiStream(String columnLabel) throws SQLException {
|
||||
return delegate.getAsciiStream(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getUnicodeStream(String columnLabel) throws SQLException {
|
||||
return delegate.getUnicodeStream(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBinaryStream(String columnLabel) throws SQLException {
|
||||
return delegate.getBinaryStream(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return delegate.getWarnings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
delegate.clearWarnings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCursorName() throws SQLException {
|
||||
return delegate.getCursorName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetMetaData getMetaData() throws SQLException {
|
||||
return delegate.getMetaData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(int columnIndex) throws SQLException {
|
||||
return delegate.getObject(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(String columnLabel) throws SQLException {
|
||||
return delegate.getObject(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findColumn(String columnLabel) throws SQLException {
|
||||
return delegate.findColumn(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getCharacterStream(int columnIndex) throws SQLException {
|
||||
return delegate.getCharacterStream(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getCharacterStream(String columnLabel) throws SQLException {
|
||||
return delegate.getCharacterStream(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
|
||||
return delegate.getBigDecimal(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
|
||||
return delegate.getBigDecimal(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeFirst() throws SQLException {
|
||||
return delegate.isBeforeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterLast() throws SQLException {
|
||||
return delegate.isAfterLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirst() throws SQLException {
|
||||
return delegate.isFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLast() throws SQLException {
|
||||
return delegate.isLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFirst() throws SQLException {
|
||||
delegate.beforeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterLast() throws SQLException {
|
||||
delegate.afterLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean first() throws SQLException {
|
||||
return delegate.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean last() throws SQLException {
|
||||
return delegate.last();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRow() throws SQLException {
|
||||
return delegate.getRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean absolute(int row) throws SQLException {
|
||||
return delegate.absolute(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean relative(int rows) throws SQLException {
|
||||
return delegate.relative(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean previous() throws SQLException {
|
||||
return delegate.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
delegate.setFetchDirection(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return delegate.getFetchDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
delegate.setFetchSize(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchSize() throws SQLException {
|
||||
return delegate.getFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() throws SQLException {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConcurrency() throws SQLException {
|
||||
return delegate.getConcurrency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rowUpdated() throws SQLException {
|
||||
return delegate.rowUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rowInserted() throws SQLException {
|
||||
return delegate.rowInserted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rowDeleted() throws SQLException {
|
||||
return delegate.rowDeleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNull(int columnIndex) throws SQLException {
|
||||
delegate.updateNull(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
|
||||
delegate.updateBoolean(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateByte(int columnIndex, byte x) throws SQLException {
|
||||
delegate.updateByte(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShort(int columnIndex, short x) throws SQLException {
|
||||
delegate.updateShort(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInt(int columnIndex, int x) throws SQLException {
|
||||
delegate.updateInt(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLong(int columnIndex, long x) throws SQLException {
|
||||
delegate.updateLong(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFloat(int columnIndex, float x) throws SQLException {
|
||||
delegate.updateFloat(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDouble(int columnIndex, double x) throws SQLException {
|
||||
delegate.updateDouble(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
|
||||
delegate.updateBigDecimal(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateString(int columnIndex, String x) throws SQLException {
|
||||
delegate.updateString(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
|
||||
delegate.updateBytes(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDate(int columnIndex, Date x) throws SQLException {
|
||||
delegate.updateDate(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTime(int columnIndex, Time x) throws SQLException {
|
||||
delegate.updateTime(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
|
||||
delegate.updateTimestamp(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
|
||||
delegate.updateAsciiStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
|
||||
delegate.updateBinaryStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
|
||||
delegate.updateCharacterStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
|
||||
delegate.updateObject(columnIndex, x, scaleOrLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObject(int columnIndex, Object x) throws SQLException {
|
||||
delegate.updateObject(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNull(String columnLabel) throws SQLException {
|
||||
delegate.updateNull(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBoolean(String columnLabel, boolean x) throws SQLException {
|
||||
delegate.updateBoolean(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateByte(String columnLabel, byte x) throws SQLException {
|
||||
delegate.updateByte(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShort(String columnLabel, short x) throws SQLException {
|
||||
delegate.updateShort(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInt(String columnLabel, int x) throws SQLException {
|
||||
delegate.updateInt(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLong(String columnLabel, long x) throws SQLException {
|
||||
delegate.updateLong(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFloat(String columnLabel, float x) throws SQLException {
|
||||
delegate.updateFloat(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDouble(String columnLabel, double x) throws SQLException {
|
||||
delegate.updateDouble(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
|
||||
delegate.updateBigDecimal(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateString(String columnLabel, String x) throws SQLException {
|
||||
delegate.updateString(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBytes(String columnLabel, byte[] x) throws SQLException {
|
||||
delegate.updateBytes(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDate(String columnLabel, Date x) throws SQLException {
|
||||
delegate.updateDate(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTime(String columnLabel, Time x) throws SQLException {
|
||||
delegate.updateTime(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
|
||||
delegate.updateTimestamp(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
|
||||
delegate.updateAsciiStream(columnLabel, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
|
||||
delegate.updateBinaryStream(columnLabel, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException {
|
||||
delegate.updateCharacterStream(columnLabel, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
|
||||
delegate.updateObject(columnLabel, x, scaleOrLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObject(String columnLabel, Object x) throws SQLException {
|
||||
delegate.updateObject(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertRow() throws SQLException {
|
||||
delegate.insertRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRow() throws SQLException {
|
||||
delegate.updateRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRow() throws SQLException {
|
||||
delegate.deleteRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshRow() throws SQLException {
|
||||
delegate.refreshRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelRowUpdates() throws SQLException {
|
||||
delegate.cancelRowUpdates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToInsertRow() throws SQLException {
|
||||
delegate.moveToInsertRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToCurrentRow() throws SQLException {
|
||||
delegate.moveToCurrentRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement getStatement() throws SQLException {
|
||||
return delegate.getStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
|
||||
return delegate.getObject(columnIndex, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ref getRef(int columnIndex) throws SQLException {
|
||||
return delegate.getRef(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getBlob(int columnIndex) throws SQLException {
|
||||
return delegate.getBlob(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getClob(int columnIndex) throws SQLException {
|
||||
return delegate.getClob(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array getArray(int columnIndex) throws SQLException {
|
||||
return delegate.getArray(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
|
||||
return delegate.getObject(columnLabel, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ref getRef(String columnLabel) throws SQLException {
|
||||
return delegate.getRef(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getBlob(String columnLabel) throws SQLException {
|
||||
return delegate.getBlob(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getClob(String columnLabel) throws SQLException {
|
||||
return delegate.getClob(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Array getArray(String columnLabel) throws SQLException {
|
||||
return delegate.getArray(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
|
||||
return delegate.getDate(columnIndex, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(String columnLabel, Calendar cal) throws SQLException {
|
||||
return delegate.getDate(columnLabel, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
|
||||
return delegate.getTime(columnIndex, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(String columnLabel, Calendar cal) throws SQLException {
|
||||
return delegate.getTime(columnLabel, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
|
||||
return delegate.getTimestamp(columnIndex, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
|
||||
return delegate.getTimestamp(columnLabel, cal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURL(int columnIndex) throws SQLException {
|
||||
return delegate.getURL(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURL(String columnLabel) throws SQLException {
|
||||
return delegate.getURL(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRef(int columnIndex, Ref x) throws SQLException {
|
||||
delegate.updateRef(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRef(String columnLabel, Ref x) throws SQLException {
|
||||
delegate.updateRef(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(int columnIndex, Blob x) throws SQLException {
|
||||
delegate.updateBlob(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(String columnLabel, Blob x) throws SQLException {
|
||||
delegate.updateBlob(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(int columnIndex, Clob x) throws SQLException {
|
||||
delegate.updateClob(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(String columnLabel, Clob x) throws SQLException {
|
||||
delegate.updateClob(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArray(int columnIndex, Array x) throws SQLException {
|
||||
delegate.updateArray(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArray(String columnLabel, Array x) throws SQLException {
|
||||
delegate.updateArray(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowId getRowId(int columnIndex) throws SQLException {
|
||||
return delegate.getRowId(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowId getRowId(String columnLabel) throws SQLException {
|
||||
return delegate.getRowId(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRowId(int columnIndex, RowId x) throws SQLException {
|
||||
delegate.updateRowId(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRowId(String columnLabel, RowId x) throws SQLException {
|
||||
delegate.updateRowId(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHoldability() throws SQLException {
|
||||
return delegate.getHoldability();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return delegate.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNString(int columnIndex, String nString) throws SQLException {
|
||||
delegate.updateNString(columnIndex, nString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNString(String columnLabel, String nString) throws SQLException {
|
||||
delegate.updateNString(columnLabel, nString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
|
||||
delegate.updateNClob(columnIndex, nClob);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
|
||||
delegate.updateNClob(columnLabel, nClob);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob getNClob(int columnIndex) throws SQLException {
|
||||
return delegate.getNClob(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob getNClob(String columnLabel) throws SQLException {
|
||||
return delegate.getNClob(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML getSQLXML(int columnIndex) throws SQLException {
|
||||
return delegate.getSQLXML(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML getSQLXML(String columnLabel) throws SQLException {
|
||||
return delegate.getSQLXML(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
|
||||
delegate.updateSQLXML(columnIndex, xmlObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
|
||||
delegate.updateSQLXML(columnLabel, xmlObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNString(int columnIndex) throws SQLException {
|
||||
return delegate.getNString(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNString(String columnLabel) throws SQLException {
|
||||
return delegate.getNString(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getNCharacterStream(int columnIndex) throws SQLException {
|
||||
return delegate.getNCharacterStream(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getNCharacterStream(String columnLabel) throws SQLException {
|
||||
return delegate.getNCharacterStream(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
|
||||
delegate.updateNCharacterStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
|
||||
delegate.updateNCharacterStream(columnLabel, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
|
||||
delegate.updateAsciiStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
|
||||
delegate.updateBinaryStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
|
||||
delegate.updateCharacterStream(columnIndex, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
|
||||
delegate.updateAsciiStream(columnLabel, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
|
||||
delegate.updateBinaryStream(columnLabel, x, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
|
||||
delegate.updateCharacterStream(columnLabel, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
|
||||
delegate.updateBlob(columnIndex, inputStream, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
|
||||
delegate.updateBlob(columnLabel, inputStream, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
|
||||
delegate.updateClob(columnIndex, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
|
||||
delegate.updateClob(columnLabel, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
|
||||
delegate.updateNClob(columnIndex, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
|
||||
delegate.updateNClob(columnLabel, reader, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
|
||||
delegate.updateNCharacterStream(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
|
||||
delegate.updateNCharacterStream(columnLabel, reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
|
||||
delegate.updateAsciiStream(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
|
||||
delegate.updateBinaryStream(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
|
||||
delegate.updateCharacterStream(columnIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
|
||||
delegate.updateAsciiStream(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
|
||||
delegate.updateBinaryStream(columnLabel, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
|
||||
delegate.updateCharacterStream(columnLabel, reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
|
||||
delegate.updateBlob(columnIndex, inputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
|
||||
delegate.updateBlob(columnLabel, inputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(int columnIndex, Reader reader) throws SQLException {
|
||||
delegate.updateClob(columnIndex, reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateClob(String columnLabel, Reader reader) throws SQLException {
|
||||
delegate.updateClob(columnLabel, reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
|
||||
delegate.updateNClob(columnIndex, reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNClob(String columnLabel, Reader reader) throws SQLException {
|
||||
delegate.updateNClob(columnLabel, reader);
|
||||
}
|
||||
|
||||
// Java 7+ methods, implemented poorly using Java 6... :(
|
||||
//@Override
|
||||
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
|
||||
//return delegate.getObject(columnIndex, type);
|
||||
return type.cast(delegate.getObject(columnIndex));
|
||||
}
|
||||
|
||||
//@Override
|
||||
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
|
||||
//return delegate.getObject(columnLabel, type);
|
||||
return type.cast(delegate.getObject(columnLabel));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return delegate.unwrap(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return delegate.isWrapperFor(iface);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Global for entire application, hopefully you know what you are doing.
|
||||
*/
|
||||
public class StaticCachingResultSetMapper extends CachingResultSetMapper {
|
||||
|
||||
private static final Map<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>> cache = new ConcurrentHashMap<CachingRowToObjectMapper.ResultSetKey, CachingRowToObjectMapper.FieldMapping<?>>();
|
||||
|
||||
public static final StaticCachingResultSetMapper instance = new StaticCachingResultSetMapper();
|
||||
|
||||
public StaticCachingResultSetMapper(final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
public StaticCachingResultSetMapper(final int arrayMaxLength) {
|
||||
super(arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
public StaticCachingResultSetMapper() {
|
||||
super(cache);
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Global for entire application, hopefully you know what you are doing.
|
||||
*/
|
||||
public class StaticCompilingResultSetMapper extends CompilingResultSetMapper {
|
||||
|
||||
private static final Map<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>> cache = new ConcurrentHashMap<CachingRowToObjectMapper.ResultSetKey, CompilingRowToObjectMapper.ResultSetToObject<?,?>>();
|
||||
|
||||
public static final StaticCompilingResultSetMapper instance = new StaticCompilingResultSetMapper();
|
||||
|
||||
public StaticCompilingResultSetMapper(final Calendar cal, final int arrayMaxLength) {
|
||||
super(cal, arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
public StaticCompilingResultSetMapper(final int arrayMaxLength) {
|
||||
super(arrayMaxLength, cache);
|
||||
}
|
||||
|
||||
public StaticCompilingResultSetMapper() {
|
||||
super(cache);
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import javax.naming.Context;
|
||||
import java.io.Closeable;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class TryClose { // tries to close certain object types
|
||||
|
||||
public static void tryClose(ResultSet obj) {
|
||||
if (obj == null)
|
||||
return;
|
||||
try {
|
||||
obj.close();
|
||||
} catch (Throwable e) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryClose(Context obj) {
|
||||
if (obj == null)
|
||||
return;
|
||||
try {
|
||||
obj.close();
|
||||
} catch (Throwable e) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryClose(Connection obj) {
|
||||
if (obj == null)
|
||||
return;
|
||||
try {
|
||||
obj.close();
|
||||
} catch (Throwable e) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryClose(Statement obj) {
|
||||
if (obj == null)
|
||||
return;
|
||||
try {
|
||||
obj.close();
|
||||
} catch (Throwable e) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryClose(Closeable obj) {
|
||||
if (obj == null)
|
||||
return;
|
||||
try {
|
||||
obj.close();
|
||||
} catch (Throwable e) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
}
|
@ -1,403 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* $Header:$
|
||||
*/
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.Types;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Currently contains all types of type mappings. Implemented using singleton pattern.
|
||||
*/
|
||||
public final class TypeMappingsFactory {
|
||||
|
||||
/* @todo: refactor! */
|
||||
|
||||
private static TypeMappingsFactory _instance;
|
||||
private static Class<?> XMLBEANS_STRING_ENUM_ABSTRACT_BASE = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
XMLBEANS_STRING_ENUM_ABSTRACT_BASE = Class.forName("org.apache.xmlbeans.StringEnumAbstractBase");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// not an error, just means XmlBeans is not available
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of this class.
|
||||
* @return TypeMappingsFactory instance.
|
||||
*/
|
||||
public static TypeMappingsFactory getInstance() {
|
||||
if (_instance == null) {
|
||||
_instance = new TypeMappingsFactory();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public static final int TYPE_UNKNOWN = 0;
|
||||
static final int TYPE_BYTE = 1;
|
||||
static final int TYPE_SHORT = 2;
|
||||
static final int TYPE_INT = 3;
|
||||
static final int TYPE_LONG = 4;
|
||||
static final int TYPE_FLOAT = 5;
|
||||
static final int TYPE_DOUBLE = 6;
|
||||
static final int TYPE_BOOLEAN = 7;
|
||||
static final int TYPE_BYTE_OBJ = 8;
|
||||
static final int TYPE_SHORT_OBJ = 9;
|
||||
static final int TYPE_INT_OBJ = 10;
|
||||
static final int TYPE_LONG_OBJ = 11;
|
||||
static final int TYPE_FLOAT_OBJ = 12;
|
||||
static final int TYPE_DOUBLE_OBJ = 13;
|
||||
static final int TYPE_BOOLEAN_OBJ = 14;
|
||||
static final int TYPE_BIG_DECIMAL = 15;
|
||||
static final int TYPE_STRING = 16;
|
||||
static final int TYPE_BYTES = 17;
|
||||
static final int TYPE_SQLDATE = 18;
|
||||
static final int TYPE_TIME = 19;
|
||||
static final int TYPE_TIMESTAMP = 20;
|
||||
static final int TYPE_STREAM = 21;
|
||||
static final int TYPE_READER = 22;
|
||||
static final int TYPE_CLOB = 23;
|
||||
static final int TYPE_BLOB = 24;
|
||||
static final int TYPE_ARRAY = 25;
|
||||
static final int TYPE_REF = 26;
|
||||
static final int TYPE_DATE = 27;
|
||||
static final int TYPE_CALENDAR = 28;
|
||||
static final int TYPE_STRUCT = 29;
|
||||
static final int TYPE_XMLBEAN_ENUM = 30;
|
||||
static final int TYPE_MAX = 31;
|
||||
|
||||
private Map<Class, Object> _primitiveDefaults;
|
||||
|
||||
//
|
||||
// keys in this map are the class of the method's return type,
|
||||
// values are the set of constants defined above all prefixed with
|
||||
// TYPE_
|
||||
//
|
||||
private Map<Class, Integer> _typeMap;
|
||||
private Map<Class, Integer> _typeSqlMap;
|
||||
|
||||
/**
|
||||
* Map a string version of sql type to sql type (java.sql.Types).
|
||||
* example: "INTEGER" maps to java.sql.Types.INTEGER
|
||||
*/
|
||||
private Map<String, Integer> _typeSqlNameMap;
|
||||
|
||||
private static Method _methodMapGet;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
TypeMappingsFactory() {
|
||||
|
||||
_primitiveDefaults = new HashMap<Class, Object>();
|
||||
_primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
|
||||
_primitiveDefaults.put(Integer.TYPE, new Integer(0));
|
||||
_primitiveDefaults.put(Long.TYPE, new Long(0));
|
||||
_primitiveDefaults.put(Byte.TYPE, new Byte((byte) 0));
|
||||
_primitiveDefaults.put(Short.TYPE, new Short((short) 0));
|
||||
_primitiveDefaults.put(Character.TYPE, new Character('\u0000'));
|
||||
_primitiveDefaults.put(Float.TYPE, new Float(0.0f));
|
||||
_primitiveDefaults.put(Double.TYPE, new Double(0.0d));
|
||||
|
||||
// Class to internal enum
|
||||
_typeMap = new HashMap<Class, Integer>(TYPE_MAX * 2);
|
||||
_typeMap.put(Boolean.TYPE, new Integer(TYPE_BOOLEAN));
|
||||
_typeMap.put(Integer.TYPE, new Integer(TYPE_INT));
|
||||
_typeMap.put(Long.TYPE, new Integer(TYPE_LONG));
|
||||
_typeMap.put(Byte.TYPE, new Integer(TYPE_BYTE));
|
||||
_typeMap.put(Short.TYPE, new Integer(TYPE_SHORT));
|
||||
_typeMap.put(Float.TYPE, new Integer(TYPE_FLOAT));
|
||||
_typeMap.put(Double.TYPE, new Integer(TYPE_DOUBLE));
|
||||
_typeMap.put(Boolean.class, new Integer(TYPE_BOOLEAN_OBJ));
|
||||
_typeMap.put(Integer.class, new Integer(TYPE_INT_OBJ));
|
||||
_typeMap.put(Long.class, new Integer(TYPE_LONG_OBJ));
|
||||
_typeMap.put(Byte.class, new Integer(TYPE_BYTE_OBJ));
|
||||
_typeMap.put(Short.class, new Integer(TYPE_SHORT_OBJ));
|
||||
_typeMap.put(Float.class, new Integer(TYPE_FLOAT_OBJ));
|
||||
_typeMap.put(Double.class, new Integer(TYPE_DOUBLE_OBJ));
|
||||
_typeMap.put(String.class, new Integer(TYPE_STRING));
|
||||
_typeMap.put(java.math.BigDecimal.class, new Integer(TYPE_BIG_DECIMAL));
|
||||
_typeMap.put(byte[].class, new Integer(TYPE_BYTES));
|
||||
_typeMap.put(java.sql.Timestamp.class, new Integer(TYPE_TIMESTAMP));
|
||||
_typeMap.put(java.sql.Time.class, new Integer(TYPE_TIME));
|
||||
_typeMap.put(java.sql.Date.class, new Integer(TYPE_SQLDATE));
|
||||
_typeMap.put(java.sql.Ref.class, new Integer(TYPE_REF));
|
||||
_typeMap.put(Blob.class, new Integer(TYPE_BLOB));
|
||||
_typeMap.put(Clob.class, new Integer(TYPE_CLOB));
|
||||
_typeMap.put(java.sql.Array.class, new Integer(TYPE_ARRAY));
|
||||
_typeMap.put(java.sql.Struct.class, new Integer(TYPE_STRUCT));
|
||||
_typeMap.put(java.io.Reader.class, new Integer(TYPE_READER));
|
||||
_typeMap.put(java.io.InputStream.class, new Integer(TYPE_STREAM));
|
||||
_typeMap.put(java.util.Date.class, new Integer(TYPE_DATE));
|
||||
_typeMap.put(java.util.Calendar.class, new Integer(TYPE_CALENDAR));
|
||||
_typeMap.put(java.util.GregorianCalendar.class, new Integer(TYPE_CALENDAR));
|
||||
if (XMLBEANS_STRING_ENUM_ABSTRACT_BASE != null) {
|
||||
_typeMap.put(XMLBEANS_STRING_ENUM_ABSTRACT_BASE, new Integer(TYPE_XMLBEAN_ENUM));
|
||||
}
|
||||
|
||||
// Class to java.sql.Types
|
||||
_typeSqlMap = new HashMap<Class, Integer>(TYPE_MAX * 2);
|
||||
_typeSqlMap.put(Boolean.TYPE, new Integer(Types.BOOLEAN));
|
||||
_typeSqlMap.put(Integer.TYPE, new Integer(Types.INTEGER));
|
||||
_typeSqlMap.put(Long.TYPE, new Integer(Types.BIGINT));
|
||||
_typeSqlMap.put(Byte.TYPE, new Integer(Types.TINYINT));
|
||||
_typeSqlMap.put(Short.TYPE, new Integer(Types.SMALLINT));
|
||||
_typeSqlMap.put(Float.TYPE, new Integer(Types.REAL));
|
||||
_typeSqlMap.put(Double.TYPE, new Integer(Types.DOUBLE));
|
||||
_typeSqlMap.put(Boolean.class, new Integer(Types.BOOLEAN));
|
||||
_typeSqlMap.put(Integer.class, new Integer(Types.INTEGER));
|
||||
_typeSqlMap.put(Long.class, new Integer(Types.BIGINT));
|
||||
_typeSqlMap.put(Byte.class, new Integer(Types.TINYINT));
|
||||
_typeSqlMap.put(Short.class, new Integer(Types.SMALLINT));
|
||||
_typeSqlMap.put(Float.class, new Integer(Types.REAL));
|
||||
_typeSqlMap.put(Double.class, new Integer(Types.DOUBLE));
|
||||
_typeSqlMap.put(String.class, new Integer(Types.VARCHAR));
|
||||
_typeSqlMap.put(java.math.BigDecimal.class, new Integer(Types.DECIMAL));
|
||||
_typeSqlMap.put(byte[].class, new Integer(Types.VARBINARY));
|
||||
_typeSqlMap.put(java.sql.Timestamp.class, new Integer(Types.TIMESTAMP));
|
||||
_typeSqlMap.put(java.sql.Time.class, new Integer(Types.TIME));
|
||||
_typeSqlMap.put(java.sql.Date.class, new Integer(Types.DATE));
|
||||
_typeSqlMap.put(java.sql.Ref.class, new Integer(Types.REF));
|
||||
_typeSqlMap.put(Blob.class, new Integer(Types.BLOB));
|
||||
_typeSqlMap.put(Clob.class, new Integer(Types.CLOB));
|
||||
_typeSqlMap.put(java.sql.Array.class, new Integer(Types.ARRAY));
|
||||
_typeSqlMap.put(java.sql.Struct.class, new Integer(Types.STRUCT));
|
||||
_typeSqlMap.put(java.util.Date.class, new Integer(Types.TIMESTAMP));
|
||||
_typeSqlMap.put(java.util.Calendar.class, new Integer(Types.TIMESTAMP));
|
||||
_typeSqlMap.put(java.util.GregorianCalendar.class, new Integer(Types.TIMESTAMP));
|
||||
if (XMLBEANS_STRING_ENUM_ABSTRACT_BASE != null) {
|
||||
_typeSqlMap.put(XMLBEANS_STRING_ENUM_ABSTRACT_BASE, new Integer(Types.VARCHAR));
|
||||
}
|
||||
|
||||
// String to java.sql.Types
|
||||
_typeSqlNameMap = new HashMap<String, Integer>(TYPE_MAX * 2);
|
||||
_typeSqlNameMap.put("BIT", new Integer(Types.BIT));
|
||||
_typeSqlNameMap.put("TINYINT", new Integer(Types.TINYINT));
|
||||
_typeSqlNameMap.put("SMALLINT", new Integer(Types.SMALLINT));
|
||||
_typeSqlNameMap.put("INTEGER", new Integer(Types.INTEGER));
|
||||
_typeSqlNameMap.put("BIGINT", new Integer(Types.BIGINT));
|
||||
_typeSqlNameMap.put("FLOAT", new Integer(Types.REAL));
|
||||
_typeSqlNameMap.put("REAL", new Integer(Types.REAL));
|
||||
_typeSqlNameMap.put("DOUBLE", new Integer(Types.DOUBLE));
|
||||
_typeSqlNameMap.put("NUMERIC", new Integer(Types.NUMERIC));
|
||||
_typeSqlNameMap.put("DECIMAL", new Integer(Types.DECIMAL));
|
||||
_typeSqlNameMap.put("CHAR", new Integer(Types.CHAR));
|
||||
_typeSqlNameMap.put("VARCHAR", new Integer(Types.VARCHAR));
|
||||
_typeSqlNameMap.put("LONGVARCHAR", new Integer(Types.LONGVARCHAR));
|
||||
_typeSqlNameMap.put("DATE", new Integer(Types.DATE));
|
||||
_typeSqlNameMap.put("TIME", new Integer(Types.TIME));
|
||||
_typeSqlNameMap.put("TIMESTAMP", new Integer(Types.TIMESTAMP));
|
||||
_typeSqlNameMap.put("BINARY", new Integer(Types.BINARY));
|
||||
_typeSqlNameMap.put("VARBINARY", new Integer(Types.VARBINARY));
|
||||
_typeSqlNameMap.put("LONGVARBINARY", new Integer(Types.LONGVARBINARY));
|
||||
_typeSqlNameMap.put("NULL", new Integer(Types.NULL));
|
||||
_typeSqlNameMap.put("OTHER", new Integer(Types.OTHER));
|
||||
_typeSqlNameMap.put("JAVA_OBJECT", new Integer(Types.JAVA_OBJECT));
|
||||
_typeSqlNameMap.put("DISTINCT", new Integer(Types.DISTINCT));
|
||||
_typeSqlNameMap.put("STRUCT", new Integer(Types.STRUCT));
|
||||
_typeSqlNameMap.put("ARRAY", new Integer(Types.ARRAY));
|
||||
_typeSqlNameMap.put("BLOB", new Integer(Types.BLOB));
|
||||
_typeSqlNameMap.put("CLOB", new Integer(Types.CLOB));
|
||||
_typeSqlNameMap.put("REF", new Integer(Types.REF));
|
||||
_typeSqlNameMap.put("DATALINK", new Integer(Types.DATALINK));
|
||||
_typeSqlNameMap.put("BOOLEAN", new Integer(Types.BOOLEAN));
|
||||
|
||||
// some JAVA synonyms
|
||||
_typeSqlNameMap.put("BYTE", new Integer(Types.TINYINT));
|
||||
_typeSqlNameMap.put("SHORT", new Integer(Types.SMALLINT));
|
||||
_typeSqlNameMap.put("INT", new Integer(Types.INTEGER));
|
||||
_typeSqlNameMap.put("LONG", new Integer(Types.BIGINT));
|
||||
|
||||
// cache the Map.get method for efficiency
|
||||
try {
|
||||
_methodMapGet = Map.class.getMethod("get", new Class[]{Object.class});
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new MapperException("Can not find java.util.Map.get(Object) method");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a type string to its SQL Type int value.
|
||||
* @param type A String containing the SQL type name.
|
||||
* @return The SQL type, TYPE_UNKNOWN if cannot convert.
|
||||
*/
|
||||
public int convertStringToSQLType(String type) {
|
||||
if (_typeSqlNameMap.containsKey(type.toUpperCase())) {
|
||||
return _typeSqlNameMap.get(type.toUpperCase());
|
||||
}
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL type of a class, start at top level class an check all super classes until match is found.
|
||||
* @param classType Class to get SQL type of.
|
||||
* @return Types.OTHER if cannot find SQL type.
|
||||
*/
|
||||
public int getSqlType(Class classType) {
|
||||
|
||||
final Class origType = classType;
|
||||
while (classType != null) {
|
||||
Integer type = _typeSqlMap.get(classType);
|
||||
if (type != null) {
|
||||
return type.intValue();
|
||||
}
|
||||
classType = classType.getSuperclass();
|
||||
}
|
||||
|
||||
//
|
||||
// special check for blobs/clobs they are interfaces not derived from
|
||||
//
|
||||
if (Blob.class.isAssignableFrom(origType)) {
|
||||
return _typeSqlMap.get(Blob.class).intValue();
|
||||
} else if (Clob.class.isAssignableFrom(origType)) {
|
||||
return _typeSqlMap.get(Clob.class).intValue();
|
||||
}
|
||||
|
||||
return Types.OTHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL type for an object.
|
||||
* @param o Object to get SQL type of.
|
||||
* @return SQL type of the object, Types.OTHER if cannot classify.
|
||||
*/
|
||||
public int getSqlType(Object o) {
|
||||
if (null == o) {
|
||||
return Types.NULL;
|
||||
}
|
||||
return getSqlType(o.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param val
|
||||
* @param args
|
||||
* @return the type
|
||||
* @throws IllegalAccessException
|
||||
* @throws java.lang.reflect.InvocationTargetException
|
||||
*/
|
||||
public Object lookupType(Object val, Object[] args)
|
||||
throws IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
return _methodMapGet.invoke(val, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type id (defined by this class) for the given class.
|
||||
* @param classType Class to get type of.
|
||||
* @return Type id of class.
|
||||
*/
|
||||
public int getTypeId(Class classType) {
|
||||
|
||||
final Class origType = classType;
|
||||
while (null != classType) {
|
||||
Integer typeObj = (Integer) _typeMap.get(classType);
|
||||
if (null != typeObj) {
|
||||
return typeObj.intValue();
|
||||
}
|
||||
classType = classType.getSuperclass();
|
||||
}
|
||||
|
||||
//
|
||||
// special check for blobs/clobs they are interfaces not derived from
|
||||
//
|
||||
if (Blob.class.isAssignableFrom(origType)) {
|
||||
return _typeMap.get(Blob.class).intValue();
|
||||
} else if (Clob.class.isAssignableFrom(origType)) {
|
||||
return _typeMap.get(Clob.class).intValue();
|
||||
}
|
||||
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a primitive legal value as opposed to null if type is primitive.
|
||||
* @param type type to get null value for.
|
||||
* @return null value for specifed type.
|
||||
*/
|
||||
public Object fixNull(Class type) {
|
||||
return type.isPrimitive() ? _primitiveDefaults.get(type) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Object array for the given array.
|
||||
*
|
||||
* @param o An array.
|
||||
* @return A new object array.
|
||||
*/
|
||||
public static Object[] toObjectArray(Object o) {
|
||||
|
||||
Class clas = o.getClass().getComponentType();
|
||||
|
||||
if (null == clas) return null;
|
||||
|
||||
Object[] arr;
|
||||
|
||||
if (clas == Boolean.TYPE) {
|
||||
boolean[] src = (boolean[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Boolean(src[i]);
|
||||
} else if (clas == Character.TYPE) {
|
||||
char[] src = (char[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Character(src[i]);
|
||||
} else if (clas == Byte.TYPE) {
|
||||
byte[] src = (byte[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Byte(src[i]);
|
||||
} else if (clas == Short.TYPE) {
|
||||
short[] src = (short[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Short(src[i]);
|
||||
} else if (clas == Integer.TYPE) {
|
||||
int[] src = (int[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Integer(src[i]);
|
||||
} else if (clas == Long.TYPE) {
|
||||
long[] src = (long[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Long(src[i]);
|
||||
} else if (clas == Float.TYPE) {
|
||||
float[] src = (float[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Float(src[i]);
|
||||
} else if (clas == Double.TYPE) {
|
||||
double[] src = (double[]) o;
|
||||
arr = new Object[src.length];
|
||||
for (int i = 0; i < src.length; i++)
|
||||
arr[i] = new Double(src[i]);
|
||||
} else {
|
||||
arr = (Object[]) o;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
@ -1,242 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
|
||||
public abstract class UpdateableDTO implements Finishable {
|
||||
private boolean finished = false;
|
||||
private Map<String, Object> changes = null;
|
||||
|
||||
private String tableName;
|
||||
private String whereClause;
|
||||
|
||||
public static final String YES = System.getProperty("UpdateableDTO.YES", "Y");
|
||||
public static final String NO = System.getProperty("UpdateableDTO.NO", "N");
|
||||
|
||||
/**
|
||||
* Will always return YES or NO from this class, so they CAN be compared with object equality '==' instead of '.equals()'
|
||||
* @param bool
|
||||
* @return
|
||||
*/
|
||||
public static String booleanToString(boolean bool){
|
||||
return bool ? YES : NO;
|
||||
}
|
||||
|
||||
public static boolean changed(Object oldValue, Object newValue){
|
||||
return oldValue != newValue && ((oldValue != null && !oldValue.equals(newValue)) || !newValue.equals(oldValue));
|
||||
}
|
||||
|
||||
public static <K, E> Object[] getUpdate(final StringBuilder sb, final Map<K, E> changes, final String tableName, final String whereClause){
|
||||
if(changes.isEmpty())
|
||||
return new Object[0];
|
||||
sb.append("UPDATE ").append(tableName).append(" SET ");
|
||||
int count = -1;
|
||||
Object[] objectsToBind = new Object[changes.size()];
|
||||
boolean notFirst = false;
|
||||
for (Map.Entry<K, E> column : changes.entrySet()) {
|
||||
if (column.getKey() == null) continue;
|
||||
if (notFirst) sb.append(",");
|
||||
else notFirst = true;
|
||||
sb.append(column.getKey()).append("=?");
|
||||
objectsToBind[++count] = column.getValue();
|
||||
}
|
||||
if(whereClause != null)
|
||||
sb.append(" ").append(whereClause);
|
||||
//System.out.println("updateRow: "+sb);
|
||||
return objectsToBind;
|
||||
}
|
||||
|
||||
public static <K, E> Object[] getInsert(final StringBuilder sb, final Map<K, E> changes, final String tableName){
|
||||
if(changes.isEmpty())
|
||||
return new Object[0];
|
||||
sb.append("INSERT INTO ").append(tableName).append(" (");
|
||||
int count = -1;
|
||||
Object[] objectsToBind = new Object[changes.size()];
|
||||
boolean notFirst = false;
|
||||
for (Map.Entry<K, E> column : changes.entrySet()) {
|
||||
if (column.getKey() == null) continue;
|
||||
if (notFirst) sb.append(",");
|
||||
else notFirst = true;
|
||||
sb.append(column.getKey());
|
||||
objectsToBind[++count] = column.getValue();
|
||||
}
|
||||
sb.append(") VALUES (?");
|
||||
for(int x = 1; x < objectsToBind.length; ++x)
|
||||
sb.append(",?");
|
||||
sb.append(")");
|
||||
//System.out.println("insertRow: "+sb);
|
||||
return objectsToBind;
|
||||
}
|
||||
|
||||
public static <K, E> int updateRow(final Connection conn, final Map<K, E> changes, final String tableName, final String whereClause, final Object... additionalBindObjects) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Object[] objectsToBind = getUpdate(sb, changes, tableName, whereClause);
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sb.toString());
|
||||
QueryMapper.bindStatement(ps, objectsToBind, additionalBindObjects == null ? new Object[0] : additionalBindObjects);
|
||||
return ps.executeUpdate();
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public static <K, E> int updateRow(final QueryMapper qm, final Map<K, E> changes, final String tableName, final String whereClause, final Object... additionalBindObjects) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Object[] objectsToBind = getUpdate(sb, changes, tableName, whereClause);
|
||||
return qm.executeUpdate(sb.toString(), objectsToBind, additionalBindObjects == null ? new Object[0] : additionalBindObjects);
|
||||
}
|
||||
|
||||
public static <K, E> int insertRow(final Connection conn, final Map<K, E> changes, final String tableName) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Object[] objectsToBind = getInsert(sb, changes, tableName);
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(sb.toString());
|
||||
QueryMapper.bindStatement(ps, objectsToBind);
|
||||
return ps.executeUpdate();
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public static <K, E> int insertRow(final QueryMapper qm, final Map<K, E> changes, final String tableName) throws SQLException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Object[] objectsToBind = getInsert(sb, changes, tableName);
|
||||
return qm.executeUpdate(sb.toString(), objectsToBind);
|
||||
}
|
||||
|
||||
public static <K, E> int deleteRow(final Connection conn, final String tableName, final String whereClause, final Object... additionalBindObjects) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = conn.prepareStatement(String.format("DELETE FROM %s %s", tableName, whereClause == null ? "" : whereClause));
|
||||
if(additionalBindObjects != null)
|
||||
QueryMapper.bindStatement(ps, additionalBindObjects);
|
||||
return ps.executeUpdate();
|
||||
} finally {
|
||||
tryClose(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public static <K, E> int deleteRow(final QueryMapper qm, final String tableName, final String whereClause, final Object... additionalBindObjects) throws SQLException {
|
||||
return qm.executeUpdate(String.format("DELETE FROM %s %s", tableName, whereClause == null ? "" : whereClause), additionalBindObjects == null ? new Object[0] : additionalBindObjects);
|
||||
}
|
||||
|
||||
protected UpdateableDTO(String tableName, String whereClause) {
|
||||
setTableName(tableName);
|
||||
this.whereClause = whereClause;
|
||||
}
|
||||
|
||||
protected String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
protected void setTableName(String tableName) {
|
||||
if(tableName == null)
|
||||
throw new NullPointerException("tableName can never be null! Insert, update, or delete would never work!");
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
protected String getWhereClause() {
|
||||
return whereClause;
|
||||
}
|
||||
|
||||
protected void setWhereClause(String whereClause) {
|
||||
this.whereClause = whereClause;
|
||||
}
|
||||
|
||||
protected final void change(String columnName, boolean oldValue, boolean newValue) {
|
||||
change(columnName, booleanToString(oldValue), booleanToString(newValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Right now this is NOT thread-safe, if this class is to be used concurrently, it needs synchronized
|
||||
*
|
||||
* This never saves the ORIGINAL value, so if you change a certain column to something new, then change it back
|
||||
* to the original, it is still counted as a change. The way to fix this would be another Map<String, Object>
|
||||
* of ORIGINAL values, but I'm not sure this is desired.
|
||||
*
|
||||
* @param columnName
|
||||
* @param newValue
|
||||
*/
|
||||
protected final boolean change(String columnName, Object oldValue, Object newValue) {
|
||||
if(finished && changed(oldValue, newValue)){
|
||||
/*
|
||||
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++");
|
||||
System.out.println("before: "+this);
|
||||
System.out.printf("changing column '%s' from '%s' to '%s'\n", columnName, oldValue, newValue);
|
||||
new Exception("Stack trace").printStackTrace(System.out);
|
||||
System.out.println("----------------------------------------------");
|
||||
*/
|
||||
if (changes == null)
|
||||
changes = new HashMap<String, Object>();
|
||||
changes.put(columnName, newValue);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasChanged() {
|
||||
return changes != null && !changes.isEmpty(); // not null would probably suffice?
|
||||
}
|
||||
|
||||
public int updateRow(Connection conn) throws SQLException {
|
||||
if (!hasChanged())
|
||||
return 0;
|
||||
return updateRow(conn, changes, this.tableName, this.whereClause, this.getAdditionalBindObjects());
|
||||
}
|
||||
|
||||
public int updateRow(QueryMapper qm) throws SQLException {
|
||||
if (!hasChanged())
|
||||
return 0;
|
||||
return updateRow(qm, changes, this.tableName, this.whereClause, this.getAdditionalBindObjects());
|
||||
}
|
||||
|
||||
public int insertRow(Connection conn) throws SQLException {
|
||||
if (!hasChanged())
|
||||
return 0;
|
||||
return insertRow(conn, changes, this.tableName);
|
||||
}
|
||||
|
||||
public int insertRow(QueryMapper qm) throws SQLException {
|
||||
if (!hasChanged())
|
||||
return 0;
|
||||
return insertRow(qm, changes, this.tableName);
|
||||
}
|
||||
|
||||
public int deleteRow(Connection conn) throws SQLException {
|
||||
return deleteRow(conn, this.tableName, this.whereClause, this.getAdditionalBindObjects());
|
||||
}
|
||||
|
||||
public int deleteRow(QueryMapper qm) throws SQLException {
|
||||
return deleteRow(qm, this.tableName, this.whereClause, this.getAdditionalBindObjects());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(ResultSet rs) throws SQLException {
|
||||
this.finished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* You will almost always want to return some objects here for your where clause
|
||||
*
|
||||
* if you need to bind a single null, return new Object[]{null}, otherwise nothing will be binded
|
||||
* if you only need to bind a single non-null object, return that object here
|
||||
* if you need to bind multiple objects, return an Object[] or a Collection
|
||||
*/
|
||||
public abstract Object getAdditionalBindObjects();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UpdateableDTO{" +
|
||||
"finished=" + finished +
|
||||
", changes=" + changes +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.jdbc.CompilingRowToObjectMapper;
|
||||
import com.moparisthebest.jdbc.ResultSetMapper;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.codegen.JdbcMapperProcessor.typeMirrorToClass;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/26/17.
|
||||
*/
|
||||
public class CompileTimeResultSetMapper {
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void mapToResultType(final Writer w, final String[] keys, final ExecutableElement eeMethod, final int arrayMaxLength, final Calendar cal) throws IOException, NoSuchMethodException, ClassNotFoundException {
|
||||
final Method m = fromExecutableElement(eeMethod);
|
||||
final Class returnType = m.getReturnType();
|
||||
final TypeMirror returnTypeMirror = eeMethod.getReturnType();
|
||||
if (returnType.isArray()) {
|
||||
toArray(w, keys, ((ArrayType) returnTypeMirror).getComponentType(), returnType.getComponentType(), arrayMaxLength, cal);
|
||||
} else if (Collection.class.isAssignableFrom(returnType)) {
|
||||
toCollection(w, keys, returnTypeMirror, returnType, ((DeclaredType) returnTypeMirror).getTypeArguments().get(0), (Class) getActualTypeArguments(m)[0], arrayMaxLength, cal);
|
||||
} else if (Map.class.isAssignableFrom(returnType)) {
|
||||
final List<? extends TypeMirror> typeArguments = ((DeclaredType) returnTypeMirror).getTypeArguments();
|
||||
final Type[] types = getActualTypeArguments(m);
|
||||
if (types[1] instanceof ParameterizedType) { // for collectionMaps
|
||||
final ParameterizedType pt = (ParameterizedType) types[1];
|
||||
final Class collectionType = (Class) pt.getRawType();
|
||||
if (Collection.class.isAssignableFrom(collectionType)) {
|
||||
final TypeMirror collectionTypeMirror = typeArguments.get(1);
|
||||
toMapCollection(w, keys,
|
||||
returnTypeMirror, returnType,
|
||||
typeArguments.get(0), (Class) types[0],
|
||||
collectionTypeMirror, collectionType,
|
||||
((DeclaredType) collectionTypeMirror).getTypeArguments().get(0), (Class) pt.getActualTypeArguments()[0],
|
||||
arrayMaxLength, cal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
toMap(w, keys, returnTypeMirror, returnType, typeArguments.get(0), (Class) types[0], typeArguments.get(1), (Class) types[1], arrayMaxLength, cal);
|
||||
} else if (Iterator.class.isAssignableFrom(returnType)) {
|
||||
if (ListIterator.class.isAssignableFrom(returnType))
|
||||
toListIterator(w, keys, ((DeclaredType) returnTypeMirror).getTypeArguments().get(0), (Class) getActualTypeArguments(m)[0], arrayMaxLength, cal);
|
||||
else
|
||||
toIterator(w, keys, ((DeclaredType) returnTypeMirror).getTypeArguments().get(0), (Class) getActualTypeArguments(m)[0], arrayMaxLength, cal);
|
||||
} else {
|
||||
toObject(w, keys, returnTypeMirror, returnType, cal);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, T> CompilingRowToObjectMapper<K, T> getRowMapper(final String[] keys, Class<T> returnTypeClass, Calendar cal, Class<?> mapValType, Class<K> mapKeyType) {
|
||||
return new CompilingRowToObjectMapper<K, T>(keys, returnTypeClass, cal, mapValType, mapKeyType);
|
||||
}
|
||||
|
||||
public void writeObject(final Writer w, final String[] keys, final TypeMirror returnTypeMirror, final Class<?> returnType, final Calendar cal) throws IOException {
|
||||
getRowMapper(keys, returnType, cal, null, null).gen(w, returnTypeMirror.toString());
|
||||
}
|
||||
|
||||
public void toObject(final Writer w, final String[] keys, final TypeMirror returnTypeMirror, final Class<?> returnType, final Calendar cal) throws IOException {
|
||||
w.write("\t\t\tif(rs.next()) {\n");
|
||||
writeObject(w, keys, returnTypeMirror, returnType, cal);
|
||||
w.write("\t\t\t\treturn ret;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Collection<E>, E> void writeCollection(final Writer w, final String[] keys, final String returnTypeString, Class<T> collectionType, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
collectionType = (Class<T>) ResultSetMapper.getConcreteClass(collectionType, ArrayList.class);
|
||||
w.write("\t\t\tfinal ");
|
||||
w.write(returnTypeString);
|
||||
w.write(" _colret = new ");
|
||||
w.write(collectionType.getCanonicalName());
|
||||
w.write(returnTypeString.substring(returnTypeString.indexOf('<')));
|
||||
w.write("();\n\t\t\twhile(rs.next()) {\n");
|
||||
writeObject(w, keys, componentTypeMirror, componentType, cal);
|
||||
w.write("\t\t\t\t_colret.add(ret);\n\t\t\t}\n");
|
||||
}
|
||||
|
||||
public <T extends Collection<E>, E> void toCollection(final Writer w, final String[] keys, final TypeMirror collectionTypeMirror, Class<T> collectionType, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
writeCollection(w, keys, collectionTypeMirror.toString(), collectionType, componentTypeMirror, componentType, arrayMaxLength, cal);
|
||||
w.write("\t\t\treturn _colret;\n");
|
||||
}
|
||||
|
||||
public <E> void toArray(final Writer w, final String[] keys, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
final String returnTypeString = componentTypeMirror.toString();
|
||||
writeCollection(w, keys, "java.util.List<" + returnTypeString + ">", ArrayList.class, componentTypeMirror, componentType, arrayMaxLength, cal);
|
||||
w.write("\t\t\treturn _colret.toArray(new ");
|
||||
w.write(returnTypeString);
|
||||
w.write("[_colret.size()]);\n");
|
||||
}
|
||||
|
||||
public <E> void toListIterator(final Writer w, final String[] keys, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
final String returnTypeString = componentTypeMirror.toString();
|
||||
writeCollection(w, keys, "java.util.List<" + returnTypeString + ">", ArrayList.class, componentTypeMirror, componentType, arrayMaxLength, cal);
|
||||
w.write("\t\t\treturn _colret.listIterator();\n");
|
||||
}
|
||||
|
||||
public <E> void toIterator(final Writer w, final String[] keys, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
final String returnTypeString = componentTypeMirror.toString();
|
||||
writeCollection(w, keys, "java.util.List<" + returnTypeString + ">", ArrayList.class, componentTypeMirror, componentType, arrayMaxLength, cal);
|
||||
w.write("\t\t\treturn _colret.iterator();\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Map<K, E>, K, E> void toMap(final Writer w, final String[] keys, final TypeMirror mapTypeMirror, Class<T> mapType, final TypeMirror mapKeyTypeMirror, Class<E> mapKeyType, final TypeMirror componentTypeMirror, Class<E> componentType, int arrayMaxLength, Calendar cal) throws IOException {
|
||||
mapType = (Class<T>) ResultSetMapper.getConcreteClass(mapType, HashMap.class);
|
||||
final String returnTypeString = mapTypeMirror.toString();
|
||||
w.write("\t\t\tfinal ");
|
||||
w.write(returnTypeString);
|
||||
w.write(" _colret = new ");
|
||||
w.write(mapType.getCanonicalName());
|
||||
w.write(returnTypeString.substring(returnTypeString.indexOf('<')));
|
||||
w.write("();\n\t\t\twhile(rs.next()) {\n");
|
||||
|
||||
//writeObject(w, keys, componentTypeMirror, componentType, cal);
|
||||
final CompilingRowToObjectMapper rm = getRowMapper(keys, componentType, cal, null, mapKeyType);
|
||||
rm.gen(w, componentTypeMirror.toString());
|
||||
w.write("\t\t\t\t_colret.put(");
|
||||
rm.extractColumnValueString(w, 1, mapKeyType);
|
||||
w.write(", ret);\n\t\t\t}\n");
|
||||
w.write("\t\t\treturn _colret;\n");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Map<K, E>, K, E extends Collection<C>, C> void toMapCollection(final Writer w, final String[] keys,
|
||||
final TypeMirror mapTypeMirror, Class<T> mapType,
|
||||
final TypeMirror mapKeyTypeMirror, Class<E> mapKeyType,
|
||||
final TypeMirror collectionTypeMirror, Class<E> collectionType,
|
||||
final TypeMirror componentTypeMirror, Class<E> componentType,
|
||||
int arrayMaxLength, Calendar cal) throws IOException {
|
||||
mapType = (Class<T>) ResultSetMapper.getConcreteClass(mapType, HashMap.class);
|
||||
collectionType = (Class<E>) ResultSetMapper.getConcreteClass(collectionType, ArrayList.class);
|
||||
final String returnTypeString = mapTypeMirror.toString();
|
||||
final String collectionTypeString = collectionTypeMirror.toString();
|
||||
w.write("\t\t\tfinal ");
|
||||
w.write(returnTypeString);
|
||||
w.write(" _colret = new ");
|
||||
w.write(mapType.getCanonicalName());
|
||||
w.write(returnTypeString.substring(returnTypeString.indexOf('<')));
|
||||
w.write("();\n\t\t\twhile(rs.next()) {\n");
|
||||
|
||||
//writeObject(w, keys, componentTypeMirror, componentType, cal);
|
||||
final CompilingRowToObjectMapper rm = getRowMapper(keys, componentType, cal, null, mapKeyType);
|
||||
rm.gen(w, componentTypeMirror.toString());
|
||||
|
||||
w.write("\t\t\t\tfinal ");
|
||||
w.write(mapKeyTypeMirror.toString());
|
||||
w.write(" _colkey = ");
|
||||
rm.extractColumnValueString(w, 1, mapKeyType);
|
||||
w.write(";\n\t\t\t\t");
|
||||
|
||||
w.write(collectionTypeString);
|
||||
w.write(" _collist = _colret.get(_colkey);\n\t\t\t\tif(_collist == null) {\n\t\t\t\t\t_collist = new ");
|
||||
w.write(collectionType.getCanonicalName());
|
||||
w.write(collectionTypeString.substring(collectionTypeString.indexOf('<')));
|
||||
w.write("();\n\t\t\t\t\t_colret.put(_colkey, _collist);\n\t\t\t\t}\n\t\t\t\t_collist.add(ret);\n\t\t\t}\n\t\t\treturn _colret;\n");
|
||||
}
|
||||
|
||||
private static Type[] getActualTypeArguments(Method m) {
|
||||
return ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method fromExecutableElement(final ExecutableElement eeMethod) throws ClassNotFoundException, NoSuchMethodException {
|
||||
final Class c = Class.forName(eeMethod.getEnclosingElement().asType().toString());
|
||||
final List<? extends VariableElement> params = eeMethod.getParameters();
|
||||
final Class<?>[] parameterTypes = new Class[params.size()];
|
||||
int count = -1;
|
||||
for (final VariableElement param : params) {
|
||||
parameterTypes[++count] = typeMirrorToClass(param.asType());
|
||||
}
|
||||
return c.getDeclaredMethod(eeMethod.getSimpleName().toString(), parameterTypes);
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.classgen.AbstractSQLParser;
|
||||
import com.moparisthebest.classgen.SQLParser;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/24/17.
|
||||
*/
|
||||
public interface JdbcMapper extends Closeable {
|
||||
|
||||
Connection getConnection();
|
||||
|
||||
@Override
|
||||
void close();
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface Mapper {
|
||||
/**
|
||||
* The jndi name of the DataSource. This is a required element for this annotation.
|
||||
*/
|
||||
String jndiName() default "";
|
||||
|
||||
boolean cachePreparedStatements() default true;
|
||||
|
||||
Class<? extends SQLParser> sqlParser() default AbstractSQLParser.class;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface SQL {
|
||||
/**
|
||||
* The SQL statement to send to the database. Required annotation element.
|
||||
*/
|
||||
String value();
|
||||
|
||||
OptionalBool cachePreparedStatement() default OptionalBool.INHERIT;
|
||||
|
||||
/**
|
||||
* Maximum array length.
|
||||
* Optional element.
|
||||
* This element has no effect on the call unless the method return type is an array.
|
||||
* When used in conjunction with the maxRows element, the size of the array generated
|
||||
* from the result set will be the smaller of maxRows and arrayMaxLength.
|
||||
* <p>
|
||||
* arrayMaxLength's default value is 1024, but may be set to zero to specify that
|
||||
* there is no size limit for the array generated from the ResultSet.
|
||||
* Since the generated array is stored in-memory, care should be taken when dealing
|
||||
* with very large ResultSets when the value of this element is set to zero.
|
||||
*/
|
||||
int arrayMaxLength() default -1;
|
||||
}
|
||||
|
||||
public enum OptionalBool {
|
||||
INHERIT,
|
||||
TRUE,
|
||||
FALSE;
|
||||
|
||||
public boolean combine(final boolean inherited) {
|
||||
switch (this) {
|
||||
case TRUE:
|
||||
return true;
|
||||
case FALSE:
|
||||
return false;
|
||||
}
|
||||
return inherited;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/24/17.
|
||||
*/
|
||||
public abstract class JdbcMapperFactory {
|
||||
|
||||
static final String SUFFIX = "Bean";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends JdbcMapper> T create(final Class<T> jdbcMapper, final Connection connection) {
|
||||
try {
|
||||
return (T) Class.forName(jdbcMapper.getName() + SUFFIX).getConstructor(Connection.class).newInstance(connection);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("could not create JdbcMapper, did the processor run at compile time?", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends JdbcMapper> T create(final Class<T> jdbcMapper) {
|
||||
return create(jdbcMapper, null);
|
||||
}
|
||||
}
|
@ -1,396 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.classgen.SQLParser;
|
||||
import com.moparisthebest.classgen.SimpleSQLParser;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic;
|
||||
import java.io.*;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/24/17.
|
||||
*/
|
||||
@SupportedAnnotationTypes("com.moparisthebest.jdbc.codegen.JdbcMapper.Mapper")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_5)
|
||||
public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
|
||||
private static final Pattern paramPattern = Pattern.compile("\\{([^}]+)\\}");
|
||||
private static final CompileTimeResultSetMapper rsm = new CompileTimeResultSetMapper();
|
||||
|
||||
private Types types;
|
||||
private TypeMirror sqlExceptionType, stringType, numberType, utilDateType, readerType, clobType,
|
||||
byteArrayType, inputStreamType, fileType, blobType
|
||||
//, clobStringType, blobStringType, arrayListObjectType
|
||||
;
|
||||
|
||||
public JdbcMapperProcessor() {
|
||||
//out.println("JdbcMapperProcessor running!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void init(final ProcessingEnvironment processingEnv) {
|
||||
super.init(processingEnv);
|
||||
this.types = processingEnv.getTypeUtils();
|
||||
final Elements elements = processingEnv.getElementUtils();
|
||||
sqlExceptionType = elements.getTypeElement(SQLException.class.getCanonicalName()).asType();
|
||||
stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
|
||||
numberType = elements.getTypeElement(Number.class.getCanonicalName()).asType();
|
||||
utilDateType = elements.getTypeElement(java.util.Date.class.getCanonicalName()).asType();
|
||||
readerType = elements.getTypeElement(Reader.class.getCanonicalName()).asType();
|
||||
clobType = elements.getTypeElement(Clob.class.getCanonicalName()).asType();
|
||||
inputStreamType = elements.getTypeElement(InputStream.class.getCanonicalName()).asType();
|
||||
fileType = elements.getTypeElement(File.class.getCanonicalName()).asType();
|
||||
blobType = elements.getTypeElement(Blob.class.getCanonicalName()).asType();
|
||||
// throws NPE:
|
||||
//byteArrayType = elements.getTypeElement(byte[].class.getCanonicalName()).asType();
|
||||
//byteArrayType = this.types.getArrayType(elements.getTypeElement(byte.class.getCanonicalName()).asType());
|
||||
//byteArrayType = elements.getTypeElement(byte.class.getCanonicalName()).asType();
|
||||
byteArrayType = types.getArrayType(types.getPrimitiveType(TypeKind.BYTE));
|
||||
/*
|
||||
clobStringType = elements.getTypeElement(ClobString.class.getCanonicalName()).asType();
|
||||
blobStringType = elements.getTypeElement(BlobString.class.getCanonicalName()).asType();
|
||||
arrayListObjectType = elements.getTypeElement(ArrayInList.ArrayListObject.class.getCanonicalName()).asType();
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
|
||||
//if(true) return false;
|
||||
if (annotations.isEmpty() || roundEnv.processingOver()) {
|
||||
// write out test classes
|
||||
return false;
|
||||
}
|
||||
if (isInitialized())
|
||||
//System.out.println("annotations: " + annotations);
|
||||
//System.out.println("roundEnv: " + roundEnv);
|
||||
for (final Element element : roundEnv.getElementsAnnotatedWith(JdbcMapper.Mapper.class))
|
||||
try {
|
||||
if (element.getKind() != ElementKind.CLASS && element.getKind() != ElementKind.INTERFACE && !element.getModifiers().contains(Modifier.ABSTRACT)) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.Mapper can only annotate an interface or abstract class", element);
|
||||
continue;
|
||||
}
|
||||
final TypeElement genClass = (TypeElement) element;
|
||||
final JdbcMapper.Mapper mapper = genClass.getAnnotation(JdbcMapper.Mapper.class);
|
||||
final SQLParser parser = new SimpleSQLParser();//(SQLParser)Class.forName(mapper.sqlParser().getCanonicalName()).newInstance();
|
||||
final String qualifiedName = genClass.getQualifiedName().toString();
|
||||
final boolean isInterface = genClass.getKind().isInterface();
|
||||
final boolean doJndi = !mapper.jndiName().isEmpty();
|
||||
Writer w = null;
|
||||
try {
|
||||
w = processingEnv.getFiler().createSourceFile(qualifiedName + JdbcMapperFactory.SUFFIX).openWriter();
|
||||
final String packageName = ((PackageElement) genClass.getEnclosingElement()).getQualifiedName().toString();
|
||||
final String className = genClass.getSimpleName() + JdbcMapperFactory.SUFFIX;
|
||||
if (!packageName.isEmpty()) {
|
||||
w.write("package ");
|
||||
w.write(packageName);
|
||||
w.write(";\n\n");
|
||||
}
|
||||
if (doJndi) {
|
||||
w.write("import javax.naming.InitialContext;\n");
|
||||
w.write("import javax.sql.DataSource;\n");
|
||||
}
|
||||
w.write("import java.sql.*;\n\n");
|
||||
w.write("import static com.moparisthebest.jdbc.TryClose.tryClose;\n\n");
|
||||
w.write("public class ");
|
||||
w.write(className);
|
||||
if (isInterface) {
|
||||
w.write(" implements ");
|
||||
} else {
|
||||
w.write(" extends ");
|
||||
}
|
||||
w.write(genClass.getSimpleName().toString());
|
||||
w.write(" {\n\n\tprivate final Connection conn;\n");
|
||||
if (doJndi) {
|
||||
w.write("\tprivate final InitialContext ctx;\n\n\tpublic ");
|
||||
w.write(className);
|
||||
w.write("() {\n\t\tthis(null);\n\t}\n");
|
||||
}
|
||||
w.write("\n\tpublic ");
|
||||
w.write(className);
|
||||
w.write("(Connection conn) {\n\t\t");
|
||||
if (doJndi) {
|
||||
w.write("InitialContext ctx = null;\n" +
|
||||
"\t\tif (conn == null)\n" +
|
||||
"\t\t\ttry {\n" +
|
||||
"\t\t\t\tctx = new InitialContext();\n" +
|
||||
"\t\t\t\tDataSource ds = (DataSource) ctx.lookup(\"");
|
||||
w.write(mapper.jndiName()); // todo: escape this? I don't think anyone needs that, for now...
|
||||
w.write("\");\n" +
|
||||
"\t\t\t\tconn = ds.getConnection();\n" +
|
||||
"\t\t\t} catch (Throwable e) {\n" +
|
||||
"\t\t\t\ttryClose(ctx);\n" +
|
||||
"\t\t\t\ttryClose(conn);\n" +
|
||||
"\t\t\t\tthrow new RuntimeException(e);\n" +
|
||||
"\t\t\t}\n" +
|
||||
"\t\tthis.conn = conn;\n" +
|
||||
"\t\tthis.ctx = ctx;"
|
||||
);
|
||||
} else {
|
||||
w.write("this.conn = conn;");
|
||||
}
|
||||
w.write("\n\t\tif (this.conn == null)\n" +
|
||||
"\t\t\tthrow new NullPointerException(\"Connection needs to be non-null for JdbcMapper...\");\n\t}\n" +
|
||||
"\n\t@Override\n\tpublic Connection getConnection() {\n\t\treturn this.conn;\n\t}\n"
|
||||
);
|
||||
|
||||
// loop through methods
|
||||
final Types typeUtils = processingEnv.getTypeUtils();
|
||||
int cachedPreparedStatements = 0;
|
||||
for (final Element methodElement : genClass.getEnclosedElements()) {
|
||||
// can only implement abstract methods
|
||||
if (methodElement.getKind() != ElementKind.METHOD || !methodElement.getModifiers().contains(Modifier.ABSTRACT))
|
||||
continue;
|
||||
final ExecutableElement eeMethod = (ExecutableElement) methodElement;
|
||||
final JdbcMapper.SQL sql = eeMethod.getAnnotation(JdbcMapper.SQL.class);
|
||||
if (sql == null || sql.value().isEmpty()) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.SQL with non-empty query is required on abstract or interface methods", methodElement);
|
||||
continue;
|
||||
}
|
||||
w.write("\n\t@Override\n\tpublic ");
|
||||
final String returnType = eeMethod.getReturnType().toString();
|
||||
w.write(returnType);
|
||||
w.write(" ");
|
||||
w.write(eeMethod.getSimpleName().toString());
|
||||
w.write('(');
|
||||
|
||||
// build query and bind param order
|
||||
final List<VariableElement> bindParams = new ArrayList<VariableElement>();
|
||||
final String sqlStatement;
|
||||
boolean sqlExceptionThrown = false;
|
||||
{
|
||||
// now parameters
|
||||
final List<? extends VariableElement> params = eeMethod.getParameters();
|
||||
final Map<String, VariableElement> paramMap = new HashMap<String, VariableElement>(params.size());
|
||||
final int numParams = params.size();
|
||||
int count = 0;
|
||||
for (final VariableElement param : params) {
|
||||
w.write("final ");
|
||||
w.write(param.asType().toString());
|
||||
w.write(' ');
|
||||
final String name = param.getSimpleName().toString();
|
||||
w.write(name);
|
||||
paramMap.put(name, param);
|
||||
if (++count != numParams)
|
||||
w.write(", ");
|
||||
}
|
||||
|
||||
// throws?
|
||||
w.write(")");
|
||||
final List<? extends TypeMirror> thrownTypes = eeMethod.getThrownTypes();
|
||||
final int numThrownTypes = thrownTypes.size();
|
||||
if (numThrownTypes > 0) {
|
||||
count = 0;
|
||||
w.write(" throws ");
|
||||
}
|
||||
for (final TypeMirror thrownType : thrownTypes) {
|
||||
sqlExceptionThrown |= typeUtils.isSameType(thrownType, sqlExceptionType);
|
||||
w.write(thrownType.toString());
|
||||
if (++count != numThrownTypes)
|
||||
w.write(", ");
|
||||
}
|
||||
w.write(" {\n");
|
||||
|
||||
final Matcher bindParamMatcher = paramPattern.matcher(sql.value());
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
while (bindParamMatcher.find()) {
|
||||
final String paramName = bindParamMatcher.group(1);
|
||||
final VariableElement bindParam = paramMap.get(paramName);
|
||||
if (bindParam == null) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("@JdbcMapper.SQL sql has bind param '%s' not in method parameter list", paramName), methodElement);
|
||||
continue;
|
||||
}
|
||||
bindParams.add(bindParam);
|
||||
bindParamMatcher.appendReplacement(sb, "?");
|
||||
}
|
||||
bindParamMatcher.appendTail(sb);
|
||||
sqlStatement = sb.toString();
|
||||
}
|
||||
|
||||
final SQLParser parsedSQl = parser.parse(sqlStatement);
|
||||
// now implementation
|
||||
w.write("\t\tPreparedStatement ps = null;\n");
|
||||
if (parsedSQl.isSelect())
|
||||
w.write("\t\tResultSet rs = null;\n");
|
||||
w.write("\t\ttry {\n\t\t\tps = ");
|
||||
final boolean cachePreparedStatements = sql.cachePreparedStatement().combine(mapper.cachePreparedStatements());
|
||||
if (cachePreparedStatements) {
|
||||
w.write("this.prepareStatement(");
|
||||
w.write(Integer.toString(cachedPreparedStatements));
|
||||
w.write(", ");
|
||||
++cachedPreparedStatements;
|
||||
} else {
|
||||
w.write("conn.prepareStatement(");
|
||||
}
|
||||
w.write('"');
|
||||
w.write(sqlStatement);
|
||||
w.write("\");\n");
|
||||
|
||||
// now bind parameters
|
||||
int count = 0;
|
||||
for (final VariableElement param : bindParams)
|
||||
setObject(w, ++count, param.getSimpleName().toString(), param.asType());
|
||||
|
||||
if (!parsedSQl.isSelect()) {
|
||||
if (returnType.equals("void")) {
|
||||
w.write("\t\t\tps.executeUpdate();\n");
|
||||
} else if (returnType.equals("int") || returnType.equals("java.lang.Integer")) {
|
||||
w.write("\t\t\treturn ps.executeUpdate();\n");
|
||||
} else {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.SQL sql other than SELECT must return either void, int, or Integer", methodElement);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
w.write("\t\t\trs = ps.executeQuery();\n");
|
||||
final String[] keys = parsedSQl.columnNames();
|
||||
if (keys == null || keys.length < 2) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.SQL sql parsed no column names, proper SQL? Wildcard? or bad parser?", methodElement);
|
||||
continue;
|
||||
}
|
||||
for (final String key : keys)
|
||||
if ("*".equals(key)) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@JdbcMapper.SQL sql parsed a wildcard column name which is not supported", methodElement);
|
||||
return false;
|
||||
}
|
||||
rsm.mapToResultType(w, keys, eeMethod, sql.arrayMaxLength(), null);
|
||||
}
|
||||
|
||||
// if no SQLException is thrown, we have to catch it here and wrap it with RuntimeException...
|
||||
if (!sqlExceptionThrown) {
|
||||
w.write("\t\t} catch(SQLException e) {\n\t\t\tthrow new RuntimeException(e);\n");
|
||||
}
|
||||
|
||||
// close things
|
||||
w.write("\t\t} finally {\n");
|
||||
if (parsedSQl.isSelect())
|
||||
w.write("\t\t\ttryClose(rs);\n");
|
||||
if (!cachePreparedStatements)
|
||||
w.write("\t\t\ttryClose(ps);\n");
|
||||
w.write("\t\t}\n");
|
||||
|
||||
w.write("\t}\n");
|
||||
}
|
||||
|
||||
if (cachedPreparedStatements > 0) {
|
||||
w.write("\n\tprivate final PreparedStatement[] psCache = new PreparedStatement[");
|
||||
w.write(Integer.toString(cachedPreparedStatements));
|
||||
w.write("];\n\n\tprivate PreparedStatement prepareStatement(final int index, final String sql) throws SQLException {\n" +
|
||||
"\t\tfinal PreparedStatement ps = psCache[index];\n" +
|
||||
"\t\treturn ps == null ? (psCache[index] = conn.prepareStatement(sql)) : ps;\n" +
|
||||
"\t}\n");
|
||||
}
|
||||
|
||||
// close method
|
||||
w.write("\n\t@Override\n\tpublic void close() {\n\t\t");
|
||||
if (cachedPreparedStatements > 0)
|
||||
w.write("for(final PreparedStatement ps : psCache)\n\t\t\ttryClose(ps);\n\t\t");
|
||||
w.write("tryClose(conn);\n");
|
||||
if (doJndi)
|
||||
w.write("\t\ttryClose(ctx);\n");
|
||||
w.write("\t}\n");
|
||||
// end close method
|
||||
|
||||
w.write("}\n");
|
||||
} finally {
|
||||
tryClose(w);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setObject(final Writer w, final int index, String variableName, final TypeMirror o) throws SQLException, IOException {
|
||||
w.write("\t\t\t");
|
||||
// we are going to put most common ones up top so it should execute faster normally
|
||||
String method = null;
|
||||
// todo: avoid string concat here
|
||||
if (o.getKind().isPrimitive() || types.isAssignable(o, stringType) || types.isAssignable(o, numberType)) {
|
||||
method = "Object";
|
||||
// java.util.Date support, put it in a Timestamp
|
||||
} else if (types.isAssignable(o, utilDateType)) {
|
||||
method = "Object";
|
||||
// might need to wrap with Timestamp
|
||||
if (types.isSameType(o, utilDateType))
|
||||
variableName = "new java.sql.Timestamp(" + variableName + ".getTime())";
|
||||
// CLOB support
|
||||
} else if (types.isAssignable(o, readerType) || types.isAssignable(o, clobType)) {
|
||||
method = "Clob";
|
||||
/*
|
||||
} else if (o instanceof ClobString) {
|
||||
ps.setObject(index, ((ClobString) o).s == null ? null : ((ClobString) o).s);
|
||||
*/
|
||||
// BLOB support
|
||||
} else if (types.isAssignable(o, byteArrayType)) {
|
||||
method = "Blob";
|
||||
variableName = "new java.io.ByteArrayInputStream(" + variableName + ")";
|
||||
} else if (types.isAssignable(o, inputStreamType) || types.isAssignable(o, blobType)) {
|
||||
method = "Blob";
|
||||
} else if (types.isAssignable(o, fileType)) {
|
||||
// todo: does this close the InputStream properly????
|
||||
w.write("\t\t\ttry {\n" +
|
||||
"\t\t\t\tps.setBlob(" + index + ", new java.io.FileInputStream(" + variableName + "));\n" +
|
||||
"\t\t\t} catch (java.io.FileNotFoundException e) {\n" +
|
||||
"\t\t\t\tthrow new SQLException(\"File to Blob FileNotFoundException\", e);\n" +
|
||||
"\t\t\t}");
|
||||
return;
|
||||
/*
|
||||
} else if (o instanceof BlobString) {
|
||||
try {
|
||||
ps.setBlob(index, ((BlobString) o).s == null ? null : new ByteArrayInputStream(((BlobString) o).s.getBytes("UTF-8")));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new SQLException("String to Blob UnsupportedEncodingException", e);
|
||||
}
|
||||
} else if (o instanceof ArrayInList.ArrayListObject) {
|
||||
ps.setArray(index, ((ArrayInList.ArrayListObject) o).getArray());
|
||||
*/
|
||||
} else {
|
||||
// probably won't get here ever, but just in case...
|
||||
method = "Object";
|
||||
}
|
||||
w.write("ps.set");
|
||||
w.write(method);
|
||||
w.write('(');
|
||||
w.write(Integer.toString(index));
|
||||
w.write(", ");
|
||||
w.write(variableName);
|
||||
w.write(");\n");
|
||||
}
|
||||
|
||||
public static Class<?> typeMirrorToClass(final TypeMirror tm) throws ClassNotFoundException {
|
||||
switch (tm.getKind()) {
|
||||
case BOOLEAN:
|
||||
return boolean.class;
|
||||
case BYTE:
|
||||
return byte.class;
|
||||
case SHORT:
|
||||
return short.class;
|
||||
case INT:
|
||||
return int.class;
|
||||
case LONG:
|
||||
return long.class;
|
||||
case CHAR:
|
||||
return char.class;
|
||||
case FLOAT:
|
||||
return float.class;
|
||||
case DOUBLE:
|
||||
return double.class;
|
||||
default:
|
||||
return Class.forName(tm.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.moparisthebest.jdbc.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/18/17.
|
||||
*/
|
||||
public class CaseInsensitiveHashMap<String, V> extends HashMap<String, V> {
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return super.get(key instanceof java.lang.String ? ((java.lang.String) key).toLowerCase() : key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return super.containsKey(key instanceof java.lang.String ? ((java.lang.String) key).toLowerCase() : key);
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
package com.moparisthebest.jdbc.util;
|
||||
|
||||
import com.moparisthebest.jdbc.MapperException;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Calendar;
|
||||
|
||||
import static com.moparisthebest.jdbc.UpdateableDTO.NO;
|
||||
import static com.moparisthebest.jdbc.UpdateableDTO.YES;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/16/17.
|
||||
*/
|
||||
public class ResultSetUtil {
|
||||
|
||||
public static Integer getObjectInt(final ResultSet rs, final int index) throws SQLException {
|
||||
final int ret = rs.getInt(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Long getObjectLong(final ResultSet rs, final int index) throws SQLException {
|
||||
final long ret = rs.getLong(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Float getObjectFloat(final ResultSet rs, final int index) throws SQLException {
|
||||
final float ret = rs.getFloat(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Double getObjectDouble(final ResultSet rs, final int index) throws SQLException {
|
||||
final double ret = rs.getDouble(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Byte getObjectByte(final ResultSet rs, final int index) throws SQLException {
|
||||
final byte ret = rs.getByte(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Short getObjectShort(final ResultSet rs, final int index) throws SQLException {
|
||||
final short ret = rs.getShort(index);
|
||||
return rs.wasNull() ? null : ret;
|
||||
}
|
||||
|
||||
public static Boolean getObjectBoolean(final ResultSet rs, final int index) throws SQLException {
|
||||
final boolean ret = rs.getBoolean(index);
|
||||
return rs.wasNull() ? null : (ret ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
public static Boolean getObjectBooleanYN(final ResultSet rs, final int index) throws SQLException {
|
||||
try {
|
||||
return getObjectBoolean(rs, index);
|
||||
} catch (SQLException e) {
|
||||
// if we are here, it wasn't a boolean or null, so try to grab a string instead
|
||||
final String bool = rs.getString(index);//.toUpperCase(); // do we want it case-insensitive?
|
||||
final boolean ret = YES.equals(bool);
|
||||
if (!ret && !NO.equals(bool))
|
||||
throw new MapperException(String.format("Implicit conversion of database string to boolean failed on column '%d'. Returned string needs to be 'Y' or 'N' and was instead '%s'.", index, bool));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean getBooleanYN(final ResultSet rs, final int index) throws SQLException {
|
||||
final Boolean ret = getObjectBooleanYN(rs, index);
|
||||
if(ret == null)
|
||||
throw new MapperException(String.format("Implicit conversion of database string to boolean failed on column '%d'. Returned string needs to be 'Y' or 'N' and was instead 'null'. If you want to accept null values, make it an object Boolean instead of primitive boolean.", index));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Timestamp getTimestamp(final ResultSet _resultSet, final Calendar _cal, final int index) throws SQLException {
|
||||
if (null == _cal)
|
||||
return _resultSet.getTimestamp(index);
|
||||
else
|
||||
return _resultSet.getTimestamp(index, _cal);
|
||||
}
|
||||
|
||||
public static Time getTime(final ResultSet _resultSet, final Calendar _cal, final int index) throws SQLException {
|
||||
if (null == _cal)
|
||||
return _resultSet.getTime(index);
|
||||
else
|
||||
return _resultSet.getTime(index, _cal);
|
||||
}
|
||||
|
||||
public static java.sql.Date getSqlDate(final ResultSet _resultSet, final Calendar _cal, final int index) throws SQLException {
|
||||
if (null == _cal)
|
||||
return _resultSet.getDate(index);
|
||||
else
|
||||
return _resultSet.getDate(index, _cal);
|
||||
}
|
||||
|
||||
public static java.util.Date getUtilDate(final ResultSet _resultSet, final Calendar _cal, final int index) throws SQLException {
|
||||
// convert explicity to java.util.Date
|
||||
// 12918 | knex does not return java.sql.Date properly from web service
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
|
||||
public static Calendar getCalendar(final ResultSet _resultSet, final Calendar _cal, final int index) throws SQLException {
|
||||
java.sql.Timestamp ts = (null == _cal) ? _resultSet.getTimestamp(index) : _resultSet.getTimestamp(index, _cal);
|
||||
if (null == ts)
|
||||
return null;
|
||||
Calendar c = (null == _cal) ? Calendar.getInstance() : (Calendar) _cal.clone();
|
||||
c.setTimeInMillis(ts.getTime());
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
com.moparisthebest.jdbc.codegen.JdbcMapperProcessor
|
@ -1,10 +0,0 @@
|
||||
package com.moparisthebest.classgentest;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/15/17.
|
||||
*/
|
||||
public interface Calculator {
|
||||
public double calc(double a, double b);
|
||||
|
||||
public java.util.Date whenGenerated();
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package com.moparisthebest.classgentest;
|
||||
|
||||
import com.moparisthebest.classgen.Compiler;
|
||||
import com.moparisthebest.classgen.MultiCompiler;
|
||||
import com.moparisthebest.classgen.StringJavaFileObject;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* This is a sample program that shows how to generate java source code, compile, and run it, all at runtime and
|
||||
* without ever touching the filesystem. It can be used for much more complicated (and usefull) things, perhaps
|
||||
* like creating Pojo instances from ResultSets. :)
|
||||
* <p>
|
||||
* You need tools.jar on your classpath, and this class in the same package as well:
|
||||
* public interface Calculator {
|
||||
* public double calc(double a, double b);
|
||||
* public java.util.Date whenGenerated();
|
||||
* }
|
||||
* <p>
|
||||
* The original idea was taken from:
|
||||
* http://mindprod.com/jgloss/javacompiler.html#SAMPLECODE
|
||||
*
|
||||
* @author moparisthebest
|
||||
*/
|
||||
public class CalculatorCompiler {
|
||||
|
||||
@Test
|
||||
public void testSingle() throws InterruptedException {
|
||||
final Compiler compiler = new Compiler();
|
||||
final Calculator mult1 = genCalc(compiler, "Multiply", "a * b");
|
||||
final Calculator hyp = genCalc(compiler, "Hypotenuse", "Math.sqrt( a*a + b*b )");
|
||||
final Calculator mult2 = genCalc(compiler, "Multiply", "a * b * 2");
|
||||
final Calculator mult3 = genCalc(compiler, "Multiply", "a * b * 3");
|
||||
final Calculator mult4 = genCalc(compiler, "Multiply", "a * b * 4");
|
||||
assertEquals(12.0, mult1.calc(3.0, 4.0), 0.01);
|
||||
assertEquals(5.0, hyp.calc(3.0, 4.0), 0.01);
|
||||
assertEquals(24.0, mult2.calc(3.0, 4.0), 0.01);
|
||||
assertEquals(48.0, mult3.calc(4.0, 4.0), 0.01);
|
||||
assertEquals(48.0, mult4.calc(3.0, 4.0), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMulti() throws InterruptedException {
|
||||
final MultiCompiler compiler = new MultiCompiler();
|
||||
final Calculator mult1 = genCalc(compiler, "Multiply", "a * Var.var", "Var", "4.0");
|
||||
final Calculator hyp = genCalc(compiler, "Hypotenuse", "Math.sqrt( a*a + Var.var*Var.var )", "Var", "4.0");
|
||||
final Calculator mult2 = genCalc(compiler, "Multiply2", "a * Var.var * 2", "Var", "4.0");
|
||||
final Calculator mult3 = genCalc(compiler, "Multiply3", "a * Var.var * 3", "Var", "4.0");
|
||||
final Calculator mult4 = genCalc(compiler, "Multiply", "a * Var.var * 4", "Var", "4.0");
|
||||
assertEquals(mult1.calc(3.0, 4.0), 12.0, 0.01);
|
||||
assertEquals(hyp.calc(3.0, 4.0), 5.0, 0.01);
|
||||
assertEquals(mult2.calc(3.0, 4.0), 24.0, 0.01);
|
||||
assertEquals(mult3.calc(4.0, 4.0), 48.0, 0.01);
|
||||
assertEquals(48.0, mult4.calc(3.0, 4.0), 0.01);
|
||||
}
|
||||
|
||||
private static String writeCalculator(String className, String expression) {
|
||||
String packageName = null;
|
||||
final int lastIndex = className.lastIndexOf(".");
|
||||
if (lastIndex != -1) {
|
||||
packageName = className.substring(0, lastIndex);
|
||||
className = className.substring(lastIndex + 1);
|
||||
}
|
||||
|
||||
return (packageName == null ? "" : "package " + packageName + ";\n") +
|
||||
"import java.util.Date;\n" +
|
||||
"public final class " + className + " implements " + Calculator.class.getName() + " {\n" +
|
||||
" public double calc(double a, double b) {\n" +
|
||||
" return " + expression + ";\n" +
|
||||
" }\n" +
|
||||
" public Date whenGenerated() {\n" +
|
||||
" return new Date(" + System.currentTimeMillis() + "L);\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
}
|
||||
|
||||
private static StringJavaFileObject writeCalculatorOb(String className, String expression) {
|
||||
return new StringJavaFileObject(className, writeCalculator(className, expression));
|
||||
}
|
||||
|
||||
private static StringJavaFileObject writeVar(String className, String expression) {
|
||||
String packageName = null;
|
||||
final int lastIndex = className.lastIndexOf(".");
|
||||
if (lastIndex != -1) {
|
||||
packageName = className.substring(0, lastIndex);
|
||||
className = className.substring(lastIndex + 1);
|
||||
}
|
||||
|
||||
return new StringJavaFileObject(className, (packageName == null ? "" : "package " + packageName + ";\n") +
|
||||
"public final class " + className + " {\n" +
|
||||
" public static final double var = " + expression + ";\n" +
|
||||
"}\n");
|
||||
}
|
||||
|
||||
public static Calculator genCalc(final Compiler compiler, final String className, final String expression) {
|
||||
// compose text of Java program on the fly.
|
||||
final String calc = writeCalculator(className, expression);
|
||||
/*
|
||||
System.out.println("calc:");
|
||||
System.out.println(calc);
|
||||
*/
|
||||
return compiler.compile(className, calc);
|
||||
}
|
||||
|
||||
public static Calculator genCalc(final MultiCompiler compiler, final String className, final String expression, final String varClass, final String varExpression) {
|
||||
// compose text of Java program on the fly.
|
||||
final StringJavaFileObject calc = writeCalculatorOb(className, expression);
|
||||
final StringJavaFileObject var = writeVar(varClass, varExpression);
|
||||
/*
|
||||
System.out.println("calc:");
|
||||
System.out.println(calc.getCharContent(true));
|
||||
System.out.println("var:");
|
||||
System.out.println(var.getCharContent(true));
|
||||
*/
|
||||
return compiler.compile(className, calc, var);
|
||||
}
|
||||
|
||||
public static double runCalc(final String className, final String expression, final double a, final double b) {
|
||||
final Calculator calc = genCalc(new Compiler(), className, expression);
|
||||
double ret = calc.calc(a, b);
|
||||
System.out.printf("%s.calc( %f, %f ) is : %f\n", className, a, b, ret);
|
||||
System.out.printf("%s generated on: %s\n", className, calc.whenGenerated());
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.jdbc.dto.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.fieldPerson1;
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.getConnection;
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.personRegular;
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class CleaningQueryMapperTest {
|
||||
|
||||
private static Connection conn;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Throwable {
|
||||
conn = getConnection();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws Throwable {
|
||||
tryClose(conn);
|
||||
}
|
||||
|
||||
protected QueryMapper qm;
|
||||
protected final ResultSetMapper rsm;
|
||||
|
||||
public CleaningQueryMapperTest(final ResultSetMapper rsm) {
|
||||
this.rsm = rsm;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void open() {
|
||||
this.qm = new QueryMapper(conn, rsm);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
tryClose(qm);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name="{0}")
|
||||
public static Collection<Object[]> getParameters()
|
||||
{
|
||||
final Cleaner<FieldPerson> personCleaner = new Cleaner<FieldPerson>() {
|
||||
@Override
|
||||
public FieldPerson clean(final FieldPerson dto) {
|
||||
dto.firstName += " " + dto.lastName;
|
||||
dto.lastName = null;
|
||||
return dto;
|
||||
}
|
||||
};
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ new CleaningResultSetMapper<FieldPerson>(personCleaner) },
|
||||
{ new CleaningCachingResultSetMapper<FieldPerson>(personCleaner) },
|
||||
{ new CleaningCompilingResultSetMapper<FieldPerson>(personCleaner) },
|
||||
});
|
||||
}
|
||||
|
||||
// fields
|
||||
|
||||
@Test
|
||||
public void testFieldRegularPerson() throws Throwable {
|
||||
final Person expected = fieldPerson1;
|
||||
final Person actual = qm.toObject(personRegular, expected.getClass(), expected.getPersonNo());
|
||||
assertEquals(expected.getFirstName() + " " + expected.getLastName(), actual.getFirstName());
|
||||
assertNull(actual.getLastName());
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.jdbc.dto.FinalDTO;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
/**
|
||||
* This test ensures the way the java compiler in-lines final variables today
|
||||
* is the same way it will in-line them tomorrow, since changes in this behavior
|
||||
* might silently break classes that are filled with reflection.
|
||||
*/
|
||||
public class FinalTest {
|
||||
|
||||
private FinalDTO object;
|
||||
|
||||
@Before
|
||||
public void before(){
|
||||
object = new FinalDTO();
|
||||
assertTrue(object.directEqualsReflection());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalPrimitiveLongDirectCantBeSet() {
|
||||
assertFalse(object.setField("finalPrimitiveLongDirect", 1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalStringDirectCantBeSet() {
|
||||
assertFalse(object.setField("finalStringDirect", "1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEffectiveFinalPrimitiveLongDirectCanBeSet() {
|
||||
assertTrue(object.setField("effectiveFinalPrimitiveLongDirect", 1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEffectiveFinalStringDirectCanBeSet() {
|
||||
assertTrue(object.setField("effectiveFinalStringDirect", "1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalPrimitiveLongConstructorCanBeSet() {
|
||||
assertTrue(object.setField("finalPrimitiveLongConstructor", 1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalStringConstructorCanBeSet() {
|
||||
assertTrue(object.setField("finalStringConstructor", "1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalLongDirectCanBeSet() {
|
||||
assertTrue(object.setField("finalLongDirect", 1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalLongConstructorCanBeSet() {
|
||||
assertTrue(object.setField("finalLongConstructor", 1L));
|
||||
}
|
||||
}
|
@ -1,374 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
import com.moparisthebest.jdbc.dto.*;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.*;
|
||||
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class QueryMapperTest {
|
||||
|
||||
private static Connection conn;
|
||||
|
||||
public static final Person fieldPerson1 = new FieldPerson(1, new Date(0), "First", "Person");
|
||||
public static final Boss fieldBoss1 = new FieldBoss(2, new Date(0), "Second", "Person", "Finance", "Second");
|
||||
public static final Boss fieldBoss2 = new FieldBoss(3, new Date(0), "Third", "Person", "Finance", null);
|
||||
public static final Boss fieldBoss3 = new FieldBoss(4, new Date(0), null, "Person", "Finance", "Fourth");
|
||||
|
||||
public static final Person setPerson1 = new SetPerson(fieldPerson1);
|
||||
public static final Boss setBoss1 = new SetBoss(fieldBoss1);
|
||||
public static final Boss setBoss2 = new SetBoss(fieldBoss2);
|
||||
public static final Boss setBoss3 = new SetBoss(fieldBoss3);
|
||||
|
||||
public static final Person reverseFieldPerson1 = new ReverseFieldPerson(fieldPerson1);
|
||||
public static final Boss reverseFieldBoss1 = new ReverseFieldBoss(fieldBoss1);
|
||||
public static final Boss reverseFieldBoss2 = new ReverseFieldBoss(fieldBoss2);
|
||||
public static final Boss reverseFieldBoss3 = new ReverseFieldBoss(fieldBoss3);
|
||||
|
||||
public static final Person reverseSetPerson1 = new ReverseSetPerson(fieldPerson1);
|
||||
public static final Boss reverseSetBoss1 = new ReverseSetBoss(fieldBoss1);
|
||||
public static final Boss reverseSetBoss2 = new ReverseSetBoss(fieldBoss2);
|
||||
public static final Boss reverseSetBoss3 = new ReverseSetBoss(fieldBoss3);
|
||||
|
||||
public static final String personRegular = "SELECT * FROM person WHERE person_no = ?";
|
||||
public static final String bossRegularAndUnderscore = "SELECT p.person_no, p.first_name AS firstName, p.last_name, p.birth_date, b.department, p.first_name " +
|
||||
"FROM person p " +
|
||||
"JOIN boss b ON p.person_no = b.person_no " +
|
||||
"WHERE p.person_no = ?";
|
||||
public static final String bossRegularAndUnderscoreReverse = "SELECT p.person_no, p.first_name, p.last_name, p.birth_date, b.department, p.first_name AS firstName " +
|
||||
"FROM person p " +
|
||||
"JOIN boss b ON p.person_no = b.person_no " +
|
||||
"WHERE p.person_no = ?";
|
||||
public static final String bossRegular = "SELECT p.person_no, p.first_name AS firstName, p.last_name, p.birth_date, b.department " +
|
||||
"FROM person p " +
|
||||
"JOIN boss b ON p.person_no = b.person_no " +
|
||||
"WHERE p.person_no = ?";
|
||||
public static final String bossUnderscore = "SELECT p.person_no, p.first_name, p.last_name, p.birth_date, b.department " +
|
||||
"FROM person p " +
|
||||
"JOIN boss b ON p.person_no = b.person_no " +
|
||||
"WHERE p.person_no = ?";
|
||||
|
||||
static {
|
||||
// load db once
|
||||
try {
|
||||
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
|
||||
Connection conn = null;
|
||||
QueryMapper qm = null;
|
||||
try {
|
||||
conn = getConnection();
|
||||
qm = new QueryMapper(conn);
|
||||
qm.executeUpdate("CREATE TABLE person (person_no NUMERIC, first_name VARCHAR(40), last_name VARCHAR(40), birth_date TIMESTAMP)");
|
||||
qm.executeUpdate("CREATE TABLE boss (person_no NUMERIC, department VARCHAR(40))");
|
||||
for (final Person person : new Person[]{fieldPerson1})
|
||||
qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", person.getPersonNo(), person.getBirthDate(), person.getLastName(), person.getFirstName());
|
||||
for (final Boss boss : new Boss[]{fieldBoss1, fieldBoss2, fieldBoss3}) {
|
||||
qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", boss.getPersonNo(), boss.getBirthDate(), boss.getLastName(), boss.getFirstName() == null ? boss.getFirst_name() : boss.getFirstName());
|
||||
qm.executeUpdate("INSERT INTO boss (person_no, department) VALUES (?, ?)", boss.getPersonNo(), boss.getDepartment());
|
||||
}
|
||||
} finally {
|
||||
tryClose(qm);
|
||||
tryClose(conn);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Connection getConnection() throws Throwable {
|
||||
return DriverManager.getConnection("jdbc:derby:memory:derbyDB;create=true");
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Throwable {
|
||||
conn = getConnection();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws Throwable {
|
||||
tryClose(conn);
|
||||
}
|
||||
|
||||
protected QueryMapper qm;
|
||||
protected final ResultSetMapper rsm;
|
||||
|
||||
public QueryMapperTest(final ResultSetMapper rsm) {
|
||||
this.rsm = rsm;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void open() {
|
||||
this.qm = new QueryMapper(conn, rsm);
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
tryClose(qm);
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name="{0}")
|
||||
public static Collection<Object[]> getParameters()
|
||||
{
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ new ResultSetMapper() },
|
||||
{ new CachingResultSetMapper() },
|
||||
{ new CaseInsensitiveMapResultSetMapper() },
|
||||
{ new CompilingResultSetMapper() },
|
||||
});
|
||||
}
|
||||
|
||||
// fields
|
||||
|
||||
@Test
|
||||
public void testFieldRegularPerson() throws Throwable {
|
||||
testPerson(fieldPerson1, personRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldRegularAndUnderscore() throws Throwable {
|
||||
testPerson(fieldBoss1, bossRegularAndUnderscore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldRegularAndUnderscoreReverse() throws Throwable {
|
||||
testPerson(fieldBoss1, bossRegularAndUnderscoreReverse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldRegular() throws Throwable {
|
||||
testPerson(fieldBoss2, bossRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldUnderscore() throws Throwable {
|
||||
testPerson(fieldBoss3, bossUnderscore);
|
||||
}
|
||||
|
||||
// sets
|
||||
|
||||
@Test
|
||||
public void testSetRegularPerson() throws Throwable {
|
||||
testPerson(setPerson1, personRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRegularAndUnderscore() throws Throwable {
|
||||
testPerson(setBoss1, bossRegularAndUnderscore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRegularAndUnderscoreReverse() throws Throwable {
|
||||
testPerson(setBoss1, bossRegularAndUnderscoreReverse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetRegular() throws Throwable {
|
||||
testPerson(setBoss2, bossRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUnderscore() throws Throwable {
|
||||
testPerson(setBoss3, bossUnderscore);
|
||||
}
|
||||
|
||||
// reverse fields
|
||||
|
||||
@Test
|
||||
public void testReverseFieldRegularPerson() throws Throwable {
|
||||
testPerson(reverseFieldPerson1, personRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseFieldRegularAndUnderscore() throws Throwable {
|
||||
testPerson(reverseFieldBoss1, bossRegularAndUnderscore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseFieldRegularAndUnderscoreReverse() throws Throwable {
|
||||
testPerson(reverseFieldBoss1, bossRegularAndUnderscoreReverse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseFieldRegular() throws Throwable {
|
||||
testPerson(reverseFieldBoss3, bossRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseFieldUnderscore() throws Throwable {
|
||||
testPerson(reverseFieldBoss2, bossUnderscore);
|
||||
}
|
||||
|
||||
// reverse sets
|
||||
|
||||
@Test
|
||||
public void testReverseSetRegularPerson() throws Throwable {
|
||||
testPerson(reverseSetPerson1, personRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseSetRegularAndUnderscore() throws Throwable {
|
||||
testPerson(reverseSetBoss1, bossRegularAndUnderscore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseSetRegularAndUnderscoreReverse() throws Throwable {
|
||||
testPerson(reverseSetBoss1, bossRegularAndUnderscoreReverse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseSetRegular() throws Throwable {
|
||||
testPerson(reverseSetBoss3, bossRegular);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseSetUnderscore() throws Throwable {
|
||||
testPerson(reverseSetBoss2, bossUnderscore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectLong() throws Throwable {
|
||||
Assert.assertEquals(new Long(1L), qm.toObject("SELECT person_no FROM person WHERE person_no = ?", Long.class, 1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectListMap() throws Throwable {
|
||||
final List<Map<String, String>> arrayMap = getListMap();
|
||||
Assert.assertEquals(arrayMap, qm.toListMap("SELECT first_name, last_name FROM person WHERE person_no < 4", arrayMap.get(0).getClass(), String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectArrayMap() throws Throwable {
|
||||
final List<Map<String, String>> arrayMap = getListMap();
|
||||
Assert.assertArrayEquals(arrayMap.toArray(new Map[arrayMap.size()]), qm.toArrayMap("SELECT first_name, last_name FROM person WHERE person_no < 4", arrayMap.get(0).getClass(), String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectMapString() throws Throwable {
|
||||
final Map<String, String> map = new HashMap<String, String>();
|
||||
for (final Person person : new Person[]{fieldPerson1, fieldBoss1, fieldBoss2})
|
||||
map.put(person.getFirstName(), person.getLastName());
|
||||
Assert.assertEquals(map, qm.toMap("SELECT first_name, last_name FROM person WHERE person_no < 4", String.class, String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectMapLongPerson() throws Throwable {
|
||||
final Map<Long, Person> map = new HashMap<Long, Person>();
|
||||
for (final Person person : new Person[]{
|
||||
qm.toObject(bossRegular, FieldBoss.class, 2),
|
||||
qm.toObject(bossRegular, FieldBoss.class, 3),
|
||||
qm.toObject(bossRegular, FieldBoss.class, 4),
|
||||
})
|
||||
map.put(person.getPersonNo(), person);
|
||||
Assert.assertEquals(map, qm.toMap("SELECT p.person_no, p.first_name AS firstName, p.last_name, p.birth_date, b.department " +
|
||||
"FROM person p " +
|
||||
"JOIN boss b ON p.person_no = b.person_no " +
|
||||
"WHERE p.person_no in (2,3,4)", Long.class, FieldBoss.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectMapLong() throws Throwable {
|
||||
final Map<Long, Long> map = new HashMap<Long, Long>();
|
||||
for (final Person person : new Person[]{fieldPerson1, fieldBoss1, fieldBoss2})
|
||||
map.put(person.getPersonNo(), person.getPersonNo());
|
||||
Assert.assertEquals(map, qm.toMap("SELECT person_no AS first_no, person_no AS last_no FROM person WHERE person_no < 4", Long.class, Long.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectLongObject() throws Throwable {
|
||||
final Long expected = fieldPerson1.getPersonNo();
|
||||
Assert.assertEquals(expected, qm.toObject("SELECT person_no FROM person WHERE person_no = ?", Long.class, expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectLongPrimitive() throws Throwable {
|
||||
final long expected = fieldPerson1.getPersonNo();
|
||||
Assert.assertEquals((Object)expected, qm.toObject("SELECT person_no FROM person WHERE person_no = ?", long.class, expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectIntPrimitive() throws Throwable {
|
||||
final int expected = (int)fieldPerson1.getPersonNo();
|
||||
Assert.assertEquals((Object)expected, qm.toObject("SELECT person_no FROM person WHERE person_no = ?", int.class, expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectLongObjectArray() throws Throwable {
|
||||
final Long[] expected = {fieldPerson1.getPersonNo()};
|
||||
Assert.assertArrayEquals(expected, qm.toArray("SELECT person_no FROM person WHERE person_no = ?", Long.class, expected[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectObjectArray() throws Throwable {
|
||||
final Long[] arr = {1L, 2L, 3L};
|
||||
Assert.assertArrayEquals(arr, qm.toObject("SELECT 1, 2, 3 FROM person WHERE person_no = ?", Long[].class, fieldPerson1.getPersonNo()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectPrimitiveArray() throws Throwable {
|
||||
final long[] arr = {1L, 2L, 3L};
|
||||
Assert.assertArrayEquals(arr, qm.toObject("SELECT 1, 2, 3 FROM person WHERE person_no = ?", long[].class, fieldPerson1.getPersonNo()));
|
||||
}
|
||||
|
||||
@Test(expected = com.moparisthebest.jdbc.MapperException.class)
|
||||
public void testNoDefaultConstructorFails() throws Throwable {
|
||||
qm.toObject("SELECT 1, 2, 3 FROM person WHERE person_no = ?", Long.class, fieldPerson1.getPersonNo());
|
||||
}
|
||||
|
||||
private List<Map<String, String>> getListMap() {
|
||||
final List<Map<String, String>> arrayMap = new ArrayList<Map<String, String>>();
|
||||
for (final Person person : new Person[]{fieldPerson1, fieldBoss1, fieldBoss2}) {
|
||||
final Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("last_name", person.getLastName());
|
||||
map.put("first_name", person.getFirstName());
|
||||
arrayMap.add(map);
|
||||
}
|
||||
return arrayMap;
|
||||
}
|
||||
|
||||
private void testPerson(final Person expected, final String query) throws Throwable {
|
||||
final Person actual = qm.toObject(query, expected.getClass(), expected.getPersonNo());
|
||||
/*
|
||||
System.out.println("expected: " + expected);
|
||||
System.out.println("actual: " + actual);
|
||||
*/
|
||||
Assert.assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseInsensitiveMap() throws Throwable {
|
||||
final Map<String, String> map = qm.toListMap("SELECT 'bob' as bob, 'tom' as tom FROM person WHERE person_no = ?", String.class, 1).get(0);
|
||||
if (rsm instanceof CaseInsensitiveMapResultSetMapper) {
|
||||
assertEquals("bob", map.get("bob"));
|
||||
assertEquals("bob", map.get("Bob"));
|
||||
assertEquals("bob", map.get("BoB"));
|
||||
assertEquals("bob", map.get("BOb"));
|
||||
assertEquals("bob", map.get("BOB"));
|
||||
assertEquals("tom", map.get("tom"));
|
||||
assertEquals("tom", map.get("Tom"));
|
||||
assertEquals("tom", map.get("ToM"));
|
||||
assertEquals("tom", map.get("TOm"));
|
||||
assertEquals("tom", map.get("TOM"));
|
||||
} else {
|
||||
assertEquals("bob", map.get("bob"));
|
||||
assertNull(map.get("Bob"));
|
||||
assertNull(map.get("BoB"));
|
||||
assertNull(map.get("BOb"));
|
||||
assertNull(map.get("BOB"));
|
||||
assertEquals("tom", map.get("tom"));
|
||||
assertNull(map.get("Tom"));
|
||||
assertNull(map.get("ToM"));
|
||||
assertNull(map.get("TOm"));
|
||||
assertNull(map.get("TOM"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,488 +0,0 @@
|
||||
package com.moparisthebest.jdbc;
|
||||
|
||||
/*
|
||||
|
||||
Derby - Class SimpleApp
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This sample program is a minimal Java application showing JDBC access to a
|
||||
* Derby database.</p>
|
||||
* <p>
|
||||
* Instructions for how to run this program are
|
||||
* given in <A HREF=example.html>example.html</A>, by default located in the
|
||||
* same directory as this source file ($DERBY_HOME/demo/programs/simple/).</p>
|
||||
* <p>
|
||||
* Derby applications can run against Derby running in an embedded
|
||||
* or a client/server framework.</p>
|
||||
* <p>
|
||||
* When Derby runs in an embedded framework, the JDBC application and Derby
|
||||
* run in the same Java Virtual Machine (JVM). The application
|
||||
* starts up the Derby engine.</p>
|
||||
* <p>
|
||||
* When Derby runs in a client/server framework, the application runs in a
|
||||
* different JVM from Derby. The application only needs to load the client
|
||||
* driver, and the connectivity framework (in this case the Derby Network
|
||||
* Server) provides network connections.</p>
|
||||
*/
|
||||
public class SimpleApp
|
||||
{
|
||||
/* the default framework is embedded*/
|
||||
private String framework = "embedded";
|
||||
private String driver = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
private String protocol = "jdbc:derby:";
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Starts the demo by creating a new instance of this class and running
|
||||
* the <code>go()</code> method.</p>
|
||||
* <p>
|
||||
* When you run this application, you may give one of the following
|
||||
* arguments:
|
||||
* <ul>
|
||||
<li><code>embedded</code> - default, if none specified. Will use
|
||||
* Derby's embedded driver. This driver is included in the derby.jar
|
||||
* file.</li>
|
||||
* <li><code>derbyclient</code> - will use the Derby client driver to
|
||||
* access the Derby Network Server. This driver is included in the
|
||||
* derbyclient.jar file.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* When you are using a client/server framework, the network server must
|
||||
* already be running when trying to obtain client connections to Derby.
|
||||
* This demo program will will try to connect to a network server on this
|
||||
* host (the localhost), see the <code>protocol</code> instance variable.
|
||||
* </p>
|
||||
* <p>
|
||||
* When running this demo, you must include the correct driver in the
|
||||
* classpath of the JVM. See <a href="example.html">example.html</a> for
|
||||
* details.
|
||||
* </p>
|
||||
* @param args This program accepts one optional argument specifying which
|
||||
* connection framework (JDBC driver) to use (see above). The default
|
||||
* is to use the embedded JDBC driver.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SimpleApp().go(args);
|
||||
System.out.println("SimpleApp finished");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Starts the actual demo activities. This includes loading the correct
|
||||
* JDBC driver, creating a database by making a connection to Derby,
|
||||
* creating a table in the database, and inserting, updating and retrieving
|
||||
* some data. Some of the retrieved data is then verified (compared) against
|
||||
* the expected results. Finally, the table is deleted and, if the embedded
|
||||
* framework is used, the database is shut down.</p>
|
||||
* <p>
|
||||
* Generally, when using a client/server framework, other clients may be
|
||||
* (or want to be) connected to the database, so you should be careful about
|
||||
* doing shutdown unless you know that no one else needs to access the
|
||||
* database until it is rebooted. That is why this demo will not shut down
|
||||
* the database unless it is running Derby embedded.</p>
|
||||
*
|
||||
* @param args - Optional argument specifying which framework or JDBC driver
|
||||
* to use to connect to Derby. Default is the embedded framework,
|
||||
* see the <code>main()</code> method for details.
|
||||
* @see #main(String[])
|
||||
*/
|
||||
void go(String[] args)
|
||||
{
|
||||
/* parse the arguments to determine which framework is desired*/
|
||||
parseArguments(args);
|
||||
|
||||
System.out.println("SimpleApp starting in " + framework + " mode");
|
||||
|
||||
/* load the desired JDBC driver */
|
||||
loadDriver();
|
||||
|
||||
/* We will be using Statement and PreparedStatement objects for
|
||||
* executing SQL. These objects, as well as Connections and ResultSets,
|
||||
* are resources that should be released explicitly after use, hence
|
||||
* the try-catch-finally pattern used below.
|
||||
* We are storing the Statement and Prepared statement object references
|
||||
* in an array list for convenience.
|
||||
*/
|
||||
Connection conn = null;
|
||||
/* This ArrayList usage may cause a warning when compiling this class
|
||||
* with a compiler for J2SE 5.0 or newer. We are not using generics
|
||||
* because we want the source to support J2SE 1.4.2 environments. */
|
||||
ArrayList statements = new ArrayList(); // list of Statements, PreparedStatements
|
||||
PreparedStatement psInsert = null;
|
||||
PreparedStatement psUpdate = null;
|
||||
Statement s = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{
|
||||
Properties props = new Properties(); // connection properties
|
||||
// providing a user name and password is optional in the embedded
|
||||
// and derbyclient frameworks
|
||||
props.put("user", "user1");
|
||||
props.put("password", "user1");
|
||||
|
||||
/* By default, the schema APP will be used when no username is
|
||||
* provided.
|
||||
* Otherwise, the schema name is the same as the user name (in this
|
||||
* case "user1" or USER1.)
|
||||
*
|
||||
* Note that user authentication is off by default, meaning that any
|
||||
* user can connect to your database using any password. To enable
|
||||
* authentication, see the Derby Developer's Guide.
|
||||
*/
|
||||
|
||||
String dbName = "derbyDB"; // the name of the database
|
||||
|
||||
/*
|
||||
* This connection specifies create=true in the connection URL to
|
||||
* cause the database to be created when connecting for the first
|
||||
* time. To remove the database, remove the directory derbyDB (the
|
||||
* same as the database name) and its contents.
|
||||
*
|
||||
* The directory derbyDB will be created under the directory that
|
||||
* the system property derby.system.home points to, or the current
|
||||
* directory (user.dir) if derby.system.home is not set.
|
||||
*/
|
||||
conn = DriverManager.getConnection(protocol + dbName
|
||||
+ ";create=true", props);
|
||||
|
||||
System.out.println("Connected to and created database " + dbName);
|
||||
|
||||
// We want to control transactions manually. Autocommit is on by
|
||||
// default in JDBC.
|
||||
conn.setAutoCommit(false);
|
||||
|
||||
/* Creating a statement object that we can use for running various
|
||||
* SQL statements commands against the database.*/
|
||||
s = conn.createStatement();
|
||||
statements.add(s);
|
||||
|
||||
// We create a table...
|
||||
s.execute("create table location(num int, addr varchar(40))");
|
||||
System.out.println("Created table location");
|
||||
|
||||
// and add a few rows...
|
||||
|
||||
/* It is recommended to use PreparedStatements when you are
|
||||
* repeating execution of an SQL statement. PreparedStatements also
|
||||
* allows you to parameterize variables. By using PreparedStatements
|
||||
* you may increase performance (because the Derby engine does not
|
||||
* have to recompile the SQL statement each time it is executed) and
|
||||
* improve security (because of Java type checking).
|
||||
*/
|
||||
// parameter 1 is num (int), parameter 2 is addr (varchar)
|
||||
psInsert = conn.prepareStatement(
|
||||
"insert into location values (?, ?)");
|
||||
statements.add(psInsert);
|
||||
|
||||
psInsert.setInt(1, 1956);
|
||||
psInsert.setString(2, "Webster St.");
|
||||
psInsert.executeUpdate();
|
||||
System.out.println("Inserted 1956 Webster");
|
||||
|
||||
psInsert.setInt(1, 1910);
|
||||
psInsert.setString(2, "Union St.");
|
||||
psInsert.executeUpdate();
|
||||
System.out.println("Inserted 1910 Union");
|
||||
|
||||
// Let's update some rows as well...
|
||||
|
||||
// parameter 1 and 3 are num (int), parameter 2 is addr (varchar)
|
||||
psUpdate = conn.prepareStatement(
|
||||
"update location set num=?, addr=? where num=?");
|
||||
statements.add(psUpdate);
|
||||
|
||||
psUpdate.setInt(1, 180);
|
||||
psUpdate.setString(2, "Grand Ave.");
|
||||
psUpdate.setInt(3, 1956);
|
||||
psUpdate.executeUpdate();
|
||||
System.out.println("Updated 1956 Webster to 180 Grand");
|
||||
|
||||
psUpdate.setInt(1, 300);
|
||||
psUpdate.setString(2, "Lakeshore Ave.");
|
||||
psUpdate.setInt(3, 180);
|
||||
psUpdate.executeUpdate();
|
||||
System.out.println("Updated 180 Grand to 300 Lakeshore");
|
||||
|
||||
|
||||
/*
|
||||
We select the rows and verify the results.
|
||||
*/
|
||||
rs = s.executeQuery(
|
||||
"SELECT num, addr FROM location ORDER BY num");
|
||||
|
||||
/* we expect the first returned column to be an integer (num),
|
||||
* and second to be a String (addr). Rows are sorted by street
|
||||
* number (num).
|
||||
*
|
||||
* Normally, it is best to use a pattern of
|
||||
* while(rs.next()) {
|
||||
* // do something with the result set
|
||||
* }
|
||||
* to process all returned rows, but we are only expecting two rows
|
||||
* this time, and want the verification code to be easy to
|
||||
* comprehend, so we use a different pattern.
|
||||
*/
|
||||
|
||||
int number; // street number retrieved from the database
|
||||
boolean failure = false;
|
||||
if (!rs.next())
|
||||
{
|
||||
failure = true;
|
||||
reportFailure("No rows in ResultSet");
|
||||
}
|
||||
|
||||
if ((number = rs.getInt(1)) != 300)
|
||||
{
|
||||
failure = true;
|
||||
reportFailure(
|
||||
"Wrong row returned, expected num=300, got " + number);
|
||||
}
|
||||
|
||||
if (!rs.next())
|
||||
{
|
||||
failure = true;
|
||||
reportFailure("Too few rows");
|
||||
}
|
||||
|
||||
if ((number = rs.getInt(1)) != 1910)
|
||||
{
|
||||
failure = true;
|
||||
reportFailure(
|
||||
"Wrong row returned, expected num=1910, got " + number);
|
||||
}
|
||||
|
||||
if (rs.next())
|
||||
{
|
||||
failure = true;
|
||||
reportFailure("Too many rows");
|
||||
}
|
||||
|
||||
if (!failure) {
|
||||
System.out.println("Verified the rows");
|
||||
}
|
||||
|
||||
// delete the table
|
||||
s.execute("drop table location");
|
||||
System.out.println("Dropped table location");
|
||||
|
||||
/*
|
||||
We commit the transaction. Any changes will be persisted to
|
||||
the database now.
|
||||
*/
|
||||
conn.commit();
|
||||
System.out.println("Committed the transaction");
|
||||
|
||||
/*
|
||||
* In embedded mode, an application should shut down the database.
|
||||
* If the application fails to shut down the database,
|
||||
* Derby will not perform a checkpoint when the JVM shuts down.
|
||||
* This means that it will take longer to boot (connect to) the
|
||||
* database the next time, because Derby needs to perform a recovery
|
||||
* operation.
|
||||
*
|
||||
* It is also possible to shut down the Derby system/engine, which
|
||||
* automatically shuts down all booted databases.
|
||||
*
|
||||
* Explicitly shutting down the database or the Derby engine with
|
||||
* the connection URL is preferred. This style of shutdown will
|
||||
* always throw an SQLException.
|
||||
*
|
||||
* Not shutting down when in a client environment, see method
|
||||
* Javadoc.
|
||||
*/
|
||||
|
||||
if (framework.equals("embedded"))
|
||||
{
|
||||
try
|
||||
{
|
||||
// the shutdown=true attribute shuts down Derby
|
||||
DriverManager.getConnection("jdbc:derby:;shutdown=true");
|
||||
|
||||
// To shut down a specific database only, but keep the
|
||||
// engine running (for example for connecting to other
|
||||
// databases), specify a database in the connection URL:
|
||||
//DriverManager.getConnection("jdbc:derby:" + dbName + ";shutdown=true");
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
if (( (se.getErrorCode() == 50000)
|
||||
&& ("XJ015".equals(se.getSQLState()) ))) {
|
||||
// we got the expected exception
|
||||
System.out.println("Derby shut down normally");
|
||||
// Note that for single database shutdown, the expected
|
||||
// SQL state is "08006", and the error code is 45000.
|
||||
} else {
|
||||
// if the error code or SQLState is different, we have
|
||||
// an unexpected exception (shutdown failed)
|
||||
System.err.println("Derby did not shut down normally");
|
||||
printSQLException(se);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle)
|
||||
{
|
||||
printSQLException(sqle);
|
||||
} finally {
|
||||
// release all open resources to avoid unnecessary memory usage
|
||||
|
||||
// ResultSet
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
rs = null;
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
printSQLException(sqle);
|
||||
}
|
||||
|
||||
// Statements and PreparedStatements
|
||||
int i = 0;
|
||||
while (!statements.isEmpty()) {
|
||||
// PreparedStatement extend Statement
|
||||
Statement st = (Statement)statements.remove(i);
|
||||
try {
|
||||
if (st != null) {
|
||||
st.close();
|
||||
st = null;
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
printSQLException(sqle);
|
||||
}
|
||||
}
|
||||
|
||||
//Connection
|
||||
try {
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
conn = null;
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
printSQLException(sqle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the appropriate JDBC driver for this environment/framework. For
|
||||
* example, if we are in an embedded environment, we load Derby's
|
||||
* embedded Driver, <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
|
||||
*/
|
||||
private void loadDriver() {
|
||||
/*
|
||||
* The JDBC driver is loaded by loading its class.
|
||||
* If you are using JDBC 4.0 (Java SE 6) or newer, JDBC drivers may
|
||||
* be automatically loaded, making this code optional.
|
||||
*
|
||||
* In an embedded environment, this will also start up the Derby
|
||||
* engine (though not any databases), since it is not already
|
||||
* running. In a client environment, the Derby engine is being run
|
||||
* by the network server framework.
|
||||
*
|
||||
* In an embedded environment, any static Derby system properties
|
||||
* must be set before loading the driver to take effect.
|
||||
*/
|
||||
try {
|
||||
Class.forName(driver).newInstance();
|
||||
System.out.println("Loaded the appropriate driver");
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
System.err.println("\nUnable to load the JDBC driver " + driver);
|
||||
System.err.println("Please check your CLASSPATH.");
|
||||
cnfe.printStackTrace(System.err);
|
||||
} catch (InstantiationException ie) {
|
||||
System.err.println(
|
||||
"\nUnable to instantiate the JDBC driver " + driver);
|
||||
ie.printStackTrace(System.err);
|
||||
} catch (IllegalAccessException iae) {
|
||||
System.err.println(
|
||||
"\nNot allowed to access the JDBC driver " + driver);
|
||||
iae.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a data verification failure to System.err with the given message.
|
||||
*
|
||||
* @param message A message describing what failed.
|
||||
*/
|
||||
private void reportFailure(String message) {
|
||||
System.err.println("\nData verification failed:");
|
||||
System.err.println('\t' + message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints details of an SQLException chain to <code>System.err</code>.
|
||||
* Details included are SQL State, Error code, Exception message.
|
||||
*
|
||||
* @param e the SQLException from which to print details.
|
||||
*/
|
||||
public static void printSQLException(SQLException e)
|
||||
{
|
||||
// Unwraps the entire exception chain to unveil the real cause of the
|
||||
// Exception.
|
||||
while (e != null)
|
||||
{
|
||||
System.err.println("\n----- SQLException -----");
|
||||
System.err.println(" SQL State: " + e.getSQLState());
|
||||
System.err.println(" Error Code: " + e.getErrorCode());
|
||||
System.err.println(" Message: " + e.getMessage());
|
||||
// for stack traces, refer to derby.log or uncomment this:
|
||||
//e.printStackTrace(System.err);
|
||||
e = e.getNextException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the arguments given and sets the values of this class' instance
|
||||
* variables accordingly - that is which framework to use, the name of the
|
||||
* JDBC driver class, and which connection protocol protocol to use. The
|
||||
* protocol should be used as part of the JDBC URL when connecting to Derby.
|
||||
* <p>
|
||||
* If the argument is "embedded" or invalid, this method will not change
|
||||
* anything, meaning that the default values will be used.</p>
|
||||
* <p>
|
||||
* @param args JDBC connection framework, either "embedded", "derbyclient".
|
||||
* Only the first argument will be considered, the rest will be ignored.
|
||||
*/
|
||||
private void parseArguments(String[] args)
|
||||
{
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("derbyclient"))
|
||||
{
|
||||
framework = "derbyclient";
|
||||
driver = "org.apache.derby.jdbc.ClientDriver";
|
||||
protocol = "jdbc:derby://localhost:1527/";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.fieldPerson1;
|
||||
import static com.moparisthebest.jdbc.QueryMapperTest.getConnection;
|
||||
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/24/17.
|
||||
*/
|
||||
public class JdbcMapperTest {
|
||||
|
||||
private static PersonDAO dao;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Throwable {
|
||||
dao = JdbcMapperFactory.create(PersonDAO.class, getConnection());
|
||||
//dao = new com.moparisthebest.jdbc.codegen.PersonDAOBean(getConnection());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws Throwable {
|
||||
tryClose(dao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws Throwable {
|
||||
assertEquals(fieldPerson1.getFirstName(), dao.getFirstName(fieldPerson1.getPersonNo()));
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.jdbc.dto.FieldPerson;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/24/17.
|
||||
*/
|
||||
@JdbcMapper.Mapper(
|
||||
// jndiName = "bob",
|
||||
cachePreparedStatements = false
|
||||
)
|
||||
public interface PersonDAO extends JdbcMapper {
|
||||
|
||||
@JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE last_name = {lastName}")
|
||||
int setFirstName(String firstName, String lastName);
|
||||
|
||||
@JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE person_no = {personNo}")
|
||||
void setFirstName(String firstName, long personNo) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("UPDATE person SET first_name = {firstName} WHERE person_no = {personNo}")
|
||||
void setFirstNameBlob(byte[] firstName, long personNo) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo}")
|
||||
String getFirstName(long personNo) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE person_no = {personNo}")
|
||||
FieldPerson getPerson(long personNo) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}")
|
||||
List<FieldPerson> getPeople(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}")
|
||||
FieldPerson[] getPeopleArray(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}")
|
||||
Iterator<FieldPerson> getPeopleIterator(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name FROM person WHERE last_name = {lastName}")
|
||||
ListIterator<FieldPerson> getPeopleListIterator(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name, person_no FROM person WHERE last_name = {lastName}")
|
||||
Map<String, FieldPerson> getPersonMap(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name, last_name, person_no FROM person WHERE last_name = {lastName}")
|
||||
Map<String, List<FieldPerson>> getPersonMapList(String lastName) throws SQLException;
|
||||
|
||||
@JdbcMapper.SQL("SELECT first_name FROM person WHERE person_no = {personNo} and last_name = {lastName}")
|
||||
String getFirstName(long personNo, String lastName) throws SQLException;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.classgen.SQLParser;
|
||||
import com.moparisthebest.classgen.SimpleSQLParser;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Created by mopar on 5/30/17.
|
||||
*/
|
||||
public class SqlParserTest {
|
||||
|
||||
private final SQLParser factory = new SimpleSQLParser();
|
||||
|
||||
@Test
|
||||
public void testSingleSelect() {
|
||||
final SQLParser ret = factory.parse("select bob from tom");
|
||||
assertTrue(ret.isSelect());
|
||||
assertArrayEquals(new String[]{null, "BOB"}, ret.columnNames());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiSelect() {
|
||||
final String[] expected = new String[]{null, "BOB", "TOM"};
|
||||
for (final String sql : new String[]{
|
||||
"select bob, tom from tom"
|
||||
, "select some_bob bob, some_tom as tom from tom"
|
||||
, "select tom.bob, some_tom as tom from tom"
|
||||
}) {
|
||||
final SQLParser ret = factory.parse(sql);
|
||||
assertTrue(ret.isSelect());
|
||||
assertArrayEquals(expected, ret.columnNames());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotSelect() {
|
||||
for (final String sql : new String[]{
|
||||
"UPDATE bob SET bob = 'bob' WHERE bob_no = 1"
|
||||
, "INSERT INTO bob (bob_no, bob) VALUES (1, 'bob')"
|
||||
, "MERGE INTO bob bla bla bla"
|
||||
}) {
|
||||
final SQLParser ret = factory.parse(sql);
|
||||
assertFalse(ret.isSelect());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public interface Boss extends Person {
|
||||
public String getDepartment();
|
||||
|
||||
public String getFirst_name();
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class FieldBoss extends FieldPerson implements Boss {
|
||||
public String department;
|
||||
public String first_name;
|
||||
|
||||
public FieldBoss() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FieldBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
this.department = department;
|
||||
this.first_name = first_name;
|
||||
}
|
||||
|
||||
public FieldBoss(Boss boss) {
|
||||
super(boss);
|
||||
this.department = boss.getDepartment();
|
||||
this.first_name = boss.getFirst_name();
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public String getFirst_name() {
|
||||
return first_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof FieldBoss)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
FieldBoss boss = (FieldBoss) o;
|
||||
|
||||
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||
if (first_name != null ? !first_name.equals(boss.first_name) : boss.first_name != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"department='" + department + '\'' +
|
||||
", first_name='" + first_name + '\'' +
|
||||
"} " + super.toString();
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class FieldPerson implements Person {
|
||||
|
||||
public long personNo;
|
||||
public Date birthDate;
|
||||
public String firstName;
|
||||
public String lastName;
|
||||
|
||||
public FieldPerson(){
|
||||
}
|
||||
|
||||
public FieldPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||
this.personNo = personNo;
|
||||
this.birthDate = birthDate;
|
||||
this.lastName = lastName;
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public FieldPerson(Person person) {
|
||||
this.personNo = person.getPersonNo();
|
||||
this.birthDate = person.getBirthDate();
|
||||
this.lastName = person.getLastName();
|
||||
this.firstName = person.getFirstName();
|
||||
}
|
||||
|
||||
public long getPersonNo() {
|
||||
return personNo;
|
||||
}
|
||||
|
||||
public Date getBirthDate() {
|
||||
return birthDate;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof FieldPerson)) return false;
|
||||
|
||||
FieldPerson person = (FieldPerson) o;
|
||||
|
||||
if (personNo != person.personNo) return false;
|
||||
if (birthDate != null ? !birthDate.equals(person.birthDate) : person.birthDate != null) return false;
|
||||
if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false;
|
||||
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (personNo ^ (personNo >>> 32));
|
||||
result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0);
|
||||
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"personNo=" + personNo +
|
||||
", birthDate=" + birthDate +
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* This class is meant to test the java compiler's in-lining behavior for final variables
|
||||
*/
|
||||
public class FinalDTO {
|
||||
|
||||
private static final boolean useReflectionNotUnsafe = true;
|
||||
|
||||
private final long finalPrimitiveLongDirect = 2L;
|
||||
private long effectiveFinalPrimitiveLongDirect = 2L;
|
||||
private final long finalPrimitiveLongConstructor;
|
||||
|
||||
{
|
||||
this.finalPrimitiveLongConstructor = 2L;
|
||||
}
|
||||
|
||||
private final String finalStringDirect = "2";
|
||||
private String effectiveFinalStringDirect = "2";
|
||||
private final String finalStringConstructor;
|
||||
|
||||
{
|
||||
this.finalStringConstructor = "2";
|
||||
}
|
||||
|
||||
private final Long finalLongDirect = 2L;
|
||||
private final Long finalLongConstructor;
|
||||
|
||||
{
|
||||
this.finalLongConstructor = 2L;
|
||||
}
|
||||
|
||||
public long getFinalPrimitiveLongDirect() {
|
||||
return finalPrimitiveLongDirect;
|
||||
}
|
||||
|
||||
public long getEffectiveFinalPrimitiveLongDirect() {
|
||||
return effectiveFinalPrimitiveLongDirect;
|
||||
}
|
||||
|
||||
public long getFinalPrimitiveLongConstructor() {
|
||||
return finalPrimitiveLongConstructor;
|
||||
}
|
||||
|
||||
public String getFinalStringDirect() {
|
||||
return finalStringDirect;
|
||||
}
|
||||
|
||||
public String getEffectiveFinalStringDirect() {
|
||||
return effectiveFinalStringDirect;
|
||||
}
|
||||
|
||||
public String getFinalStringConstructor() {
|
||||
return finalStringConstructor;
|
||||
}
|
||||
|
||||
public Long getFinalLongDirect() {
|
||||
return finalLongDirect;
|
||||
}
|
||||
|
||||
public Long getFinalLongConstructor() {
|
||||
return finalLongConstructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FinalTest{" +
|
||||
"finalPrimitiveLongDirect=" + finalPrimitiveLongDirect +
|
||||
", reflection finalPrimitiveLongDirect=" + getField("finalPrimitiveLongDirect") +
|
||||
", effectiveFinalPrimitiveLongDirect=" + effectiveFinalPrimitiveLongDirect +
|
||||
", reflection effectiveFinalPrimitiveLongDirect=" + getField("effectiveFinalPrimitiveLongDirect") +
|
||||
", finalPrimitiveLongConstructor=" + finalPrimitiveLongConstructor +
|
||||
", reflection finalPrimitiveLongConstructor=" + getField("finalPrimitiveLongConstructor") +
|
||||
", finalStringDirect=" + finalStringDirect +
|
||||
", reflection finalStringDirect=" + getField("finalStringDirect") +
|
||||
", effectiveFinalStringDirect=" + effectiveFinalStringDirect +
|
||||
", reflection effectiveFinalStringDirect=" + getField("effectiveFinalStringDirect") +
|
||||
", finalStringConstructor=" + finalStringConstructor +
|
||||
", reflection finalStringConstructor=" + getField("finalStringConstructor") +
|
||||
", finalLongDirect=" + finalLongDirect +
|
||||
", reflection finalLongDirect=" + getField("finalLongDirect") +
|
||||
", finalLongConstructor=" + finalLongConstructor +
|
||||
", reflection finalLongConstructor=" + getField("finalLongConstructor") +
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean directEqualsReflection() {
|
||||
return directEqualsReflection(finalPrimitiveLongDirect, "finalPrimitiveLongDirect")
|
||||
&& directEqualsReflection(effectiveFinalPrimitiveLongDirect, "effectiveFinalPrimitiveLongDirect")
|
||||
&& directEqualsReflection(finalPrimitiveLongConstructor, "finalPrimitiveLongConstructor")
|
||||
&& directEqualsReflection(finalStringDirect, "finalStringDirect")
|
||||
&& directEqualsReflection(effectiveFinalStringDirect, "effectiveFinalStringDirect")
|
||||
&& directEqualsReflection(finalStringConstructor, "finalStringConstructor")
|
||||
&& directEqualsReflection(finalLongDirect, "finalLongDirect")
|
||||
&& directEqualsReflection(finalLongConstructor, "finalLongConstructor")
|
||||
;
|
||||
}
|
||||
|
||||
private boolean directEqualsReflection(final Object object, final String fieldName) {
|
||||
return equals(object, getField(fieldName));
|
||||
}
|
||||
|
||||
public Object getField(final String fieldName) {
|
||||
return getField(this, fieldName);
|
||||
}
|
||||
|
||||
public boolean setField(final String fieldName, final Object fieldValue) {
|
||||
setField(this, fieldName, fieldValue);
|
||||
return directEqualsReflection();
|
||||
}
|
||||
|
||||
public static boolean equals(Object a, Object b) {
|
||||
return (a == b) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
private static Object getField(final Object object, final String fieldName) {
|
||||
try {
|
||||
final Field field = object.getClass().getDeclaredField(fieldName);
|
||||
if (useReflectionNotUnsafe) {
|
||||
field.setAccessible(true);
|
||||
return field.get(object);
|
||||
} else {
|
||||
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
|
||||
final long offset = unsafe.objectFieldOffset(field);
|
||||
|
||||
if (field.getType().isPrimitive()) {
|
||||
if (field.getType().equals(long.class))
|
||||
return unsafe.getLong(object, offset);
|
||||
else
|
||||
throw new RuntimeException("unsupported primitive type");
|
||||
} else
|
||||
return unsafe.getObject(object, offset);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setField(final Object object, final String fieldName, final Object fieldValue) {
|
||||
try {
|
||||
final Field field = object.getClass().getDeclaredField(fieldName);
|
||||
if (useReflectionNotUnsafe) {
|
||||
field.setAccessible(true);
|
||||
field.set(object, fieldValue);
|
||||
} else {
|
||||
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
|
||||
final long offset = unsafe.objectFieldOffset(field);
|
||||
|
||||
if (field.getType().isPrimitive()) {
|
||||
if (fieldValue instanceof Long)
|
||||
unsafe.putLong(object, offset, (Long) fieldValue);
|
||||
else
|
||||
throw new RuntimeException("unsupported primitive type");
|
||||
} else
|
||||
unsafe.putObject(object, offset, fieldValue);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
final FinalDTO object = new FinalDTO();
|
||||
System.out.println("1: " + object);
|
||||
setField(object, "finalPrimitiveLongDirect", 1L);
|
||||
System.out.println("2: " + object);
|
||||
setField(object, "finalPrimitiveLongConstructor", 1L);
|
||||
System.out.println("3: " + object);
|
||||
setField(object, "finalStringDirect", "1");
|
||||
System.out.println("4: " + object);
|
||||
setField(object, "finalStringConstructor", "1");
|
||||
System.out.println("5: " + object);
|
||||
setField(object, "finalLongDirect", 1L);
|
||||
System.out.println("6: " + object);
|
||||
setField(object, "finalLongConstructor", 1L);
|
||||
System.out.println("7: " + object);
|
||||
setField(object, "effectiveFinalPrimitiveLongDirect", 1L);
|
||||
System.out.println("8: " + object);
|
||||
setField(object, "effectiveFinalStringDirect", "1");
|
||||
System.out.println("9: " + object);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public interface Person {
|
||||
|
||||
public long getPersonNo();
|
||||
|
||||
public Date getBirthDate();
|
||||
|
||||
public String getFirstName();
|
||||
|
||||
public String getLastName();
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class ReverseFieldBoss extends ReverseFieldPerson implements Boss {
|
||||
public String department;
|
||||
public String firstName;
|
||||
|
||||
public ReverseFieldBoss() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ReverseFieldBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
this.department = department;
|
||||
this.firstName = first_name;
|
||||
}
|
||||
|
||||
public ReverseFieldBoss(Boss boss) {
|
||||
super(boss);
|
||||
this.department = boss.getDepartment();
|
||||
this.firstName = boss.getFirst_name();
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public String getFirst_name() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ReverseFieldBoss)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
ReverseFieldBoss boss = (ReverseFieldBoss) o;
|
||||
|
||||
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||
if (firstName != null ? !firstName.equals(boss.firstName) : boss.firstName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"department='" + department + '\'' +
|
||||
", firstName='" + firstName + '\'' +
|
||||
"} " + super.toString();
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class ReverseFieldPerson implements Person {
|
||||
|
||||
public long personNo;
|
||||
public Date birthDate;
|
||||
public String first_name;
|
||||
public String lastName;
|
||||
|
||||
public ReverseFieldPerson(){
|
||||
}
|
||||
|
||||
public ReverseFieldPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||
this.personNo = personNo;
|
||||
this.birthDate = birthDate;
|
||||
this.lastName = lastName;
|
||||
this.first_name = firstName;
|
||||
}
|
||||
|
||||
public ReverseFieldPerson(Person person) {
|
||||
this.personNo = person.getPersonNo();
|
||||
this.birthDate = person.getBirthDate();
|
||||
this.lastName = person.getLastName();
|
||||
this.first_name = person.getFirstName();
|
||||
}
|
||||
|
||||
public long getPersonNo() {
|
||||
return personNo;
|
||||
}
|
||||
|
||||
public Date getBirthDate() {
|
||||
return birthDate;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return first_name;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ReverseFieldPerson)) return false;
|
||||
|
||||
ReverseFieldPerson person = (ReverseFieldPerson) o;
|
||||
|
||||
if (personNo != person.personNo) return false;
|
||||
if (birthDate != null ? !birthDate.equals(person.birthDate) : person.birthDate != null) return false;
|
||||
if (first_name != null ? !first_name.equals(person.first_name) : person.first_name != null) return false;
|
||||
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (personNo ^ (personNo >>> 32));
|
||||
result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0);
|
||||
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"personNo=" + personNo +
|
||||
", birthDate=" + birthDate +
|
||||
", first_name='" + first_name + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class ReverseSetBoss extends ReverseSetPerson implements Boss {
|
||||
public String department;
|
||||
public String firstName;
|
||||
|
||||
public ReverseSetBoss() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ReverseSetBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
this.department = department;
|
||||
this.firstName = first_name;
|
||||
}
|
||||
|
||||
public ReverseSetBoss(Boss boss) {
|
||||
super(boss);
|
||||
this.department = boss.getDepartment();
|
||||
this.firstName = boss.getFirst_name();
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public String getFirst_name() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ReverseSetBoss)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
ReverseSetBoss boss = (ReverseSetBoss) o;
|
||||
|
||||
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||
if (firstName != null ? !firstName.equals(boss.firstName) : boss.firstName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"department='" + department + '\'' +
|
||||
", firstName='" + firstName + '\'' +
|
||||
"} " + super.toString();
|
||||
}
|
||||
|
||||
public void setDepartment(String department) {
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class ReverseSetPerson extends ReverseFieldPerson {
|
||||
public ReverseSetPerson() {
|
||||
}
|
||||
|
||||
public ReverseSetPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
}
|
||||
|
||||
public ReverseSetPerson(Person person) {
|
||||
super(person);
|
||||
}
|
||||
|
||||
public void setPersonNo(long personNo) {
|
||||
this.personNo = personNo;
|
||||
}
|
||||
|
||||
public void setBirthDate(Date birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public void setFirst_name(String first_name) {
|
||||
this.first_name = first_name;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class SetBoss extends SetPerson implements Boss {
|
||||
protected String department;
|
||||
protected String first_name;
|
||||
|
||||
public SetBoss() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SetBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
this.department = department;
|
||||
this.first_name = first_name;
|
||||
}
|
||||
|
||||
public SetBoss(Boss boss) {
|
||||
super(boss);
|
||||
this.department = boss.getDepartment();
|
||||
this.first_name = boss.getFirst_name();
|
||||
}
|
||||
|
||||
public String getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public String getFirst_name() {
|
||||
return first_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof SetBoss)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
SetBoss boss = (SetBoss) o;
|
||||
|
||||
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||
if (first_name != null ? !first_name.equals(boss.first_name) : boss.first_name != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"{" +
|
||||
"department='" + department + '\'' +
|
||||
", first_name='" + first_name + '\'' +
|
||||
"} " + super.toString();
|
||||
}
|
||||
|
||||
public void setDepartment(String department) {
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public void setFirst_name(String first_name) {
|
||||
this.first_name = first_name;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.moparisthebest.jdbc.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mopar on 6/10/14.
|
||||
*/
|
||||
public class SetPerson extends FieldPerson {
|
||||
public SetPerson() {
|
||||
}
|
||||
|
||||
public SetPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||
super(personNo, birthDate, firstName, lastName);
|
||||
}
|
||||
|
||||
public SetPerson(Person person) {
|
||||
super(person);
|
||||
}
|
||||
|
||||
public void setPersonNo(long personNo) {
|
||||
this.personNo = personNo;
|
||||
}
|
||||
|
||||
public void setBirthDate(Date birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
}
|
5
pom.xml
5
pom.xml
@ -214,6 +214,11 @@
|
||||
<artifactId>xbean</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.moparisthebest.jdbcmapper</groupId>
|
||||
<artifactId>querymapper</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<build>
|
||||
|
Loading…
Reference in New Issue
Block a user