baliuka 2003/03/09 09:14:19
Modified: dbutils/src/java/org/apache/commons/dbutils DbUtils.java
ProcedureUtils.java ResultSetHandler.java
ScalarHandler.java
dbutils/src/test/org/apache/commons/dbutils Demo.java
ProcedureUtilsTest.java
Added: dbutils/src/java/org/apache/commons/dbutils DbException.java
Log:
Added more tests, changed handler interface
Revision Changes Path
1.12 +5 -5
jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/DbUtils.java
Index: DbUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/DbUtils.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- DbUtils.java 8 Mar 2003 20:35:05 -0000 1.11
+++ DbUtils.java 9 Mar 2003 17:14:18 -0000 1.12
@@ -67,7 +67,7 @@
public static abstract class ListAdapter extends ArrayList implements
ResultSetHandler{
- final public Object handle(ResultSet rs)throws SQLException{
+ final public Object handle(ResultSet rs,Object[] params)throws SQLException{
while(rs.next()){
add(fetch(rs));
@@ -97,7 +97,7 @@
do{
rs = stmt.getResultSet();
- rsh.handle(rs);
+ rsh.handle(rs,vals);
}while(stmt.getMoreResults());
@@ -141,7 +141,7 @@
rethrow( sqle, query, vals);
}
- return rsh.handle(rs);
+ return rsh.handle(rs,vals);
} finally {
closeQuietly(rs);
@@ -253,7 +253,7 @@
return ((Number) executeQuery(connection, query, vals,
new ResultSetHandler(){
- public Object handle(ResultSet rs)throws SQLException{
+ public Object handle(ResultSet rs, Object[] params)throws SQLException{
ResultSetMetaData rsmd = rs.getMetaData();
if(rsmd.getColumnCount() > 1 ){
throwMultipleResults(query, vals);
@@ -286,7 +286,7 @@
return ((Object[]) executeQuery(connection, query, vals,
new ResultSetHandler(){
- public Object handle(ResultSet rs)throws SQLException{
+ public Object handle(ResultSet rs,Object[] params)throws SQLException{
if (rs.next()) {
return resultSetToArray(rs);
1.3 +158 -164
jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ProcedureUtils.java
Index: ProcedureUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ProcedureUtils.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ProcedureUtils.java 8 Mar 2003 20:35:05 -0000 1.2
+++ ProcedureUtils.java 9 Mar 2003 17:14:19 -0000 1.3
@@ -66,62 +66,6 @@
import com.thoughtworks.qdox.model.*;
/**
- * sample:
- * class DAO {
- *
- * static interface Procedure{
- * int execute(int p1);
- * }
- *
- * static interface Procedure2{
- * int execute2(int p1, int p2);
- * }
- *
- * static private scalarProc(Class cls, String sql){
- * ProcedureUtils.register(cls, sql, new ScalarHandlerImpl() );
- *
- * }
- * static{
- *
- * scalarProc(Procedure.class,
- * "SELECT COUNT(*) FROM MY_TABLE WHERE VALUE < $1"
- * );
- *
- * salarProc(Procedure.class,
- * "SELECT SUM(VALUE) - $2 FROM MY_TABLE WHERE VALUE > $1"
- *
- * );
- * }
- *
- * static Procedure getProcedure(){
- * return (Procedure)ProcedureUtils.getInstance(Procedure.class,
- * currentConnection());
- * }
- *
- * static Procedure getProcedure2(){
- * return (Procedure2)ProcedureUtils.getInstance(Procedure2.class,
- * currentConnection());
- * }
- *
- *
- * public static int main( String args ){
- *
- * System.out.println(getProcedure().execute(0) + getProcedure2().execute(1,3));
- *
- * }
- * }
- *
- * TODO:
- *
- * interface MyDAO{
- *
- * @sql SELECT MAX(VALUE) FROM MY_TABLE WHERE VALUE < $1
- * int getMaxLesThan(int p1);
- *
- * @sql SELECT COUNT(*) FROM MY_TABLE WHERE VALUE < $1 and VALUE >= $2
- * int getCount(int p1, int p2);
- * }
- *
*
* @author baliuka
*/
@@ -130,6 +74,8 @@
private static final Map PROCEDURES = new HashMap();
private static final Map PREDEFINED_HANDLERS = new HashMap();
private static final ResultSetHandler SCALAR_HANDLER = new ScalarHandler();
+ private static final String UPDATE_TAG = "update";
+ private static final String QUERY_TAG = "query";
static class ProcedureDescriptor{
@@ -149,7 +95,7 @@
}
- private static ProcedureDescriptor compile(Method proc, String sqlStr,
+ static ProcedureDescriptor compile(Method proc, String sqlStr,
ResultSetHandler handler,boolean update){
java.util.ArrayList indexes = new java.util.ArrayList();
@@ -180,8 +126,8 @@
if( i != sql.length - 1 ){
continue;
}else {
- i++;
- }
+ i++;
+ }
}
if(arg){
@@ -189,8 +135,8 @@
sb.append('?');
digit.delete(0, digit.length() );
}
- if( i < sql.length ){
- sb.append(sql[i]);
+ if( i < sql.length ){
+ sb.append(sql[i]);
}
escape = false;
arg = false;
@@ -214,12 +160,12 @@
}
for( Iterator i = indexes.iterator(); i.hasNext(); ){
- int param = ((Number)i.next()).intValue();
- if(param == 0 || param > proc.getParameterTypes().length ){
- throw new IllegalArgumentException( "extra prameter " +
- i + " in " + proc);
+ int param = ((Number)i.next()).intValue();
+ if(param == 0 || param > proc.getParameterTypes().length ){
+ throw new IllegalArgumentException( "extra prameter " +
+ i + " in " + proc);
}
-
+
}
ProcedureDescriptor descriptor = new ProcedureDescriptor();
@@ -243,31 +189,8 @@
return descriptor;
}
-
- private static void register( Method proc, String sql,
- ResultSetHandler handler){
- if(handler == null){
- throw new NullPointerException("handler is null");
- }
- register( proc, sql, handler, false);
- }
-
- private static void register(Method proc, String sql){
- register( proc, sql, null, false);
- }
-
-
- private static void register( Method proc, String sql,
- ResultSetHandler handler, boolean update ){
- if(!proc.getDeclaringClass().isInterface()){
- throw new IllegalArgumentException(proc.getDeclaringClass().getName() +
" is not an interface");
- }
- ProcedureDescriptor des = compile(proc,sql, handler, update );
- PROCEDURES.put(proc,des);
-
- }
-
- private static Method findMethod(Class cls, JavaMethod jmethod){
+
+ static Method findMethod(Class cls, JavaMethod jmethod){
Method methods[] = cls.getDeclaredMethods();
for(int i=0; i< methods.length; i++ ){
@@ -296,40 +219,86 @@
throw new IllegalStateException("metadata not found for " + jmethod);
}
- private static ResultSetHandler findHandler(Method method,
- JavaMethod jmethod){
-
-
- ResultSetHandler handler = null;
-
- String name = null;
-
- DocletTag tag = jmethod.getTagByName("handler");
- if(tag != null ){
- name = tag.getValue();
- if(name != null){
- return (ResultSetHandler)PREDEFINED_HANDLERS.get(name);
- }
- }
-
- if( name == null && method.getReturnType().isPrimitive() ){
- return SCALAR_HANDLER;
- }
-
- if(name != null){
- try{
- handler = (ResultSetHandler)method.getDeclaringClass().
- getClassLoader().loadClass(name).newInstance();
- }catch(Exception e){
- throw new IllegalStateException( e.getMessage() + ":" + handler + " " + name
+
- " not found in " + method );
- }
+ static ResultSetHandler findHandler(Method method, JavaMethod jmethod){
+
+
+ ResultSetHandler handler = null;
+
+ String name = null;
+
+ DocletTag tag = jmethod.getTagByName("handler");
+
+ if(tag != null ){
+ name = tag.getValue();
+
+ name = (name == null || name.trim().length() == 0 ? null : name.trim()
);
+ }
+
+ handler = (ResultSetHandler)PREDEFINED_HANDLERS.get(name);
+
+ if(name != null && handler != null ){
+
+ return handler;
+ }
+
+
+ if( name == null && method.getReturnType().isPrimitive() ){
+
+ return SCALAR_HANDLER;
+ }
+
+
+ if(name != null){
+ String imports[] = jmethod.getParentClass().
+ getParentSource().getImports();
+ String names[] = {
+ name,
+ jmethod.getParentClass().getPackage() + "." + name,
+ "org.apache.commons.dbutils." + name
+ };
+
+
+ ClassLoader loader = method.getDeclaringClass().getClassLoader();
+
+ try{
+
+ for(int i = 0; i < names.length; i++){
+
+ try{
+
+ return
(ResultSetHandler)loader.loadClass(names[i]).newInstance();
+
+ }catch(ClassNotFoundException cnfe){
+
+ }
+
+ }
+ for(int i = 0; i < imports.length; i++){
+
+ try{
+ if(imports[i].endsWith( name )){
+ return
(ResultSetHandler)loader.loadClass(imports[i]).newInstance();
+ }else if(imports[i].endsWith("*")){
+
+ return (ResultSetHandler)loader.loadClass(
+ imports[i].substring(0,imports[i].length() - 1 ) +
name).newInstance();
+ }
+
+ }catch(ClassNotFoundException cnfe){
+
+ }
+ }
+
+ }catch(Exception e){
+ throw new IllegalStateException( e.getMessage() + ":" + name +
+ " not found for " + method );
+ }
+ }
+
+ throw new IllegalStateException( "Handler not found for " + method );
}
- return handler;
- }
-
- private static Map buildProcedures(Class cls){
+ static Map buildProcedures(Class cls){
String res = cls.getName().replace('.','/') + ".java";
InputStream is = cls.getClassLoader().getResourceAsStream(res);
@@ -346,38 +315,43 @@
for( int i = 0; i< jmethods.length; i++ ){
- DocletTag tag = jmethods[i].getTagByName("sql");
- if(tag == null){
- throw new IllegalStateException("no @sql attribute in " + res + " "
+ jmethods[i]);
+ DocletTag queryTag = jmethods[i].getTagByName(QUERY_TAG);
+ DocletTag updateTag = jmethods[i].getTagByName(UPDATE_TAG);
+
+ if(queryTag == null && updateTag == null ){
+ throw new IllegalStateException("no [dbutils] attributes (" +
QUERY_TAG +
+ "," + UPDATE_TAG + ") in " + res + " " + jmethods[i]);
}
- String sql = tag.getValue();
+ String sql = updateTag == null ? queryTag.getValue() :
updateTag.getValue();
Method method = findMethod(cls, jmethods[i] );
- boolean update = jmethods[i].getTagByName("update") != null;
+ boolean update = updateTag != null;
ResultSetHandler handler = null;
if( !update ){
- handler = findHandler(method,jmethods[i] );
+ handler = findHandler(method,jmethods[i] );
}
-
- desctiptors.put( method,
- compile( method, sql, handler, update ));
+
+ desctiptors.put( method,
+ compile( method, sql, handler, update ));
}
- return desctiptors;
+ return desctiptors;
}
- //TODO:
- private static Object convert( Class convertTo, Object obj ){
- return obj;
+ //TODO: ConvertUtils
+ static Object convert( Class to, Object from ){
+
+ return from;
}
+
public static Object getInstance(Class cls, Connection connection){
Map descriptors = (Map)PROCEDURES.get(cls);
if(descriptors == null){
- descriptors = buildProcedures(cls);
- PROCEDURES.put(cls, descriptors);
+ descriptors = buildProcedures(cls);
+ PROCEDURES.put(cls, descriptors);
}
@@ -406,38 +380,58 @@
}
return pargs;
}
- //TODO: some way to handle SQLException
+
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
- if(method.getDeclaringClass() == Object.class ){
- return null;
- }
-
- ProcedureDescriptor descriptor =
(ProcedureDescriptor)descriptors.get(method);
-
- if(descriptor == null){
+ try{
- throw new IllegalStateException("no descriptor found for " +
method);
+ if(method.getDeclaringClass() == Object.class ){
+
+ return method.invoke(connection,args);
+ }
- }
-
- if(!descriptor.update){
- return convert( method.getReturnType(), DbUtils.executeQuery(
connection,
- descriptor.jdbcSQL,
- prepareArgs(descriptor,args),
- descriptor.handler
- ));
- }else{
- int updateCount = DbUtils.executeUpdate( connection,
- descriptor.jdbcSQL,
- prepareArgs(descriptor,args)
- );
+ ProcedureDescriptor descriptor =
(ProcedureDescriptor)descriptors.get(method);
- if(method.getReturnType() == Void.TYPE ){
- return null;
- }else {
- return new Integer(updateCount);
+ if(descriptor == null){
+
+ throw new IllegalStateException("no descriptor found for " +
method);
+
}
+
+ if(!descriptor.update){
+ return convert( method.getReturnType(), DbUtils.executeQuery(
connection,
+ descriptor.jdbcSQL,
+ prepareArgs(descriptor,args),
+ descriptor.handler
+ ));
+ }else{
+ int updateCount = DbUtils.executeUpdate( connection,
+ descriptor.jdbcSQL,
+ prepareArgs(descriptor,args)
+ );
+
+ if(method.getReturnType() == Void.TYPE ){
+ return null;
+ }else {
+ return new Integer(updateCount);
+ }
+ }
+ }catch(RuntimeException re){
+
+ throw re;
+
+ }catch(Exception e){
+
+ Class exeptions[] = method.getExceptionTypes();
+ for( int i = 0; i< exeptions.length; i++){
+
+ if(exeptions[i] == e.getClass() ){
+ throw e;
+ }
+ }
+
+ throw new DbException(e, method.toString() );
+
}
}
1.2 +1 -1
jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ResultSetHandler.java
Index: ResultSetHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ResultSetHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ResultSetHandler.java 8 Mar 2003 20:35:05 -0000 1.1
+++ ResultSetHandler.java 9 Mar 2003 17:14:19 -0000 1.2
@@ -7,6 +7,6 @@
*/
public interface ResultSetHandler{
- public Object handle(java.sql.ResultSet rs)throws java.sql.SQLException;
+ public Object handle(java.sql.ResultSet rs,Object params[])throws
java.sql.SQLException;
}
1.2 +2 -1
jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ScalarHandler.java
Index: ScalarHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/ScalarHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ScalarHandler.java 8 Mar 2003 20:35:05 -0000 1.1
+++ ScalarHandler.java 9 Mar 2003 17:14:19 -0000 1.2
@@ -11,7 +11,7 @@
public ScalarHandler() {
}
- public Object handle(ResultSet rs)throws SQLException{
+ public Object handle(ResultSet rs,Object[] params)throws SQLException{
if (rs.next()) {
Object result = rs.getObject(1);
@@ -20,4 +20,5 @@
throw new SQLException();
}
+
}
1.1
jakarta-commons-sandbox/dbutils/src/java/org/apache/commons/dbutils/DbException.java
Index: DbException.java
===================================================================
package org.apache.commons.dbutils;
/**
*
* @author baliuka
*/
public class DbException extends java.lang.RuntimeException {
private Throwable cause;
/**
* Creates a new instance of <code>DbException</code> without detail message.
*/
public DbException(Throwable cause) {
this.cause = cause;
}
/**
* Constructs an instance of <code>DbException</code> with the specified detail
message.
* @param msg the detail message.
*/
public DbException(Throwable cause,String msg) {
super(msg);
this.cause = cause;
}
/**
* Constructs an instance of <code>DbException</code> with the specified detail
message.
* @param msg the detail message.
*/
public DbException(String msg) {
super(msg);
}
public Throwable getCause(){
return cause;
}
}
1.2 +26 -13
jakarta-commons-sandbox/dbutils/src/test/org/apache/commons/dbutils/Demo.java
Index: Demo.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/test/org/apache/commons/dbutils/Demo.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Demo.java 8 Mar 2003 20:35:05 -0000 1.1
+++ Demo.java 9 Mar 2003 17:14:19 -0000 1.2
@@ -2,43 +2,56 @@
package org.apache.commons.dbutils;
/**
- *
+ * this file is used for metadata and must be in classpath at runtime
* @author baliuka
*/
public interface Demo {
/**
- [EMAIL PROTECTED] CREATE TABLE TBL (ID INT NOT NULL PRIMARY KEY, NAME
VARCHAR(128))
- [EMAIL PROTECTED]
+ [EMAIL PROTECTED] CREATE TABLE TBL (ID INT NOT NULL PRIMARY KEY, NAME
VARCHAR(128))
*/
void create();
/**
- [EMAIL PROTECTED] DROP TABLE TBL
- [EMAIL PROTECTED]
+ [EMAIL PROTECTED] DROP TABLE TBL
*/
void drop();
/**
- [EMAIL PROTECTED] SELECT COUNT(1) > 0 FROM TBL WHERE ID=$1
+ [EMAIL PROTECTED] SELECT COUNT(1) > 0 FROM TBL WHERE ID=$1
*/
public boolean exists(int id);
/**
- [EMAIL PROTECTED] INSERT INTO TBL (ID) VALUES($1)
- [EMAIL PROTECTED]
- */
- public int addId(int id);
+ [EMAIL PROTECTED] INSERT INTO TBL (ID, NAME) VALUES($1,$2)
+ */
+ public int add(int id,String name);
/**
- [EMAIL PROTECTED] DELETE FROM TBL
- [EMAIL PROTECTED]
- */
+ [EMAIL PROTECTED] DELETE FROM TBL
+ */
public void clear();
+ /**
+ [EMAIL PROTECTED] SELECT ID, NAME FROM TBL
+ [EMAIL PROTECTED] DemoHandler
+ */
+ public int print();
+ /**
+ [EMAIL PROTECTED] SELECT SELECT As FROM TBL
+ *
+ */
+ public void error()throws java.sql.SQLException;
+
+ /**
+ [EMAIL PROTECTED] SELECT SELECT As FROM TBL
+ *
+ */
+
+ public void undeclaredError();
}
1.2 +43 -4
jakarta-commons-sandbox/dbutils/src/test/org/apache/commons/dbutils/ProcedureUtilsTest.java
Index: ProcedureUtilsTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/dbutils/src/test/org/apache/commons/dbutils/ProcedureUtilsTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProcedureUtilsTest.java 8 Mar 2003 20:35:05 -0000 1.1
+++ ProcedureUtilsTest.java 9 Mar 2003 17:14:19 -0000 1.2
@@ -41,24 +41,63 @@
return suite;
}
+ private Demo getDemo(){
+ return(Demo)ProcedureUtils.getInstance(Demo.class ,connection);
+ }
+
public void testCreate() {
- Demo demo = (Demo)ProcedureUtils.getInstance(Demo.class ,connection);
+ Demo demo = getDemo();
try{
demo.drop();
}catch(Exception e){e.printStackTrace();}
demo.create();
}
+
public void testGetInstance() {
- Demo demo = (Demo)ProcedureUtils.getInstance(Demo.class ,connection);
+ Demo demo = getDemo();
demo.clear();
assertTrue( !demo.exists(1) );
- assertTrue( demo.addId(1) == 1 );
+ assertTrue( demo.add(1,"test") == 1 );
assertTrue( demo.exists(1) );
-
+ for( int i = 0; i< 10;i++){
+ demo.add(i + 2,"test" + i);
+ }
+ demo.print();
+ demo.clear();
+
}
+ public void testSQLException() {
+
+ try{
+
+ getDemo().error();
+ fail("must throw SQException");
+
+ }catch(SQLException ok){
+
+ }catch(Exception e){
+ fail(e.getMessage());
+ }
+
+ }
+
+ public void testUndeclaredSQLException() {
+
+ try{
+
+ getDemo().undeclaredError();
+ fail("must throw DbException");
+
+ }catch(DbException ok){
+
+ }catch(Exception e){
+ fail(e.getMessage());
+ }
+
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]