You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2022/01/24 08:49:00 UTC

[empire-db] branch version3 updated: EMPIREDB-362 DBReader Closeable

This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/version3 by this push:
     new 8b2bf59  EMPIREDB-362 DBReader Closeable
8b2bf59 is described below

commit 8b2bf59de74943e00c0f1b8160273fcd231ba6b7
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Mon Jan 24 09:48:58 2022 +0100

    EMPIREDB-362 DBReader Closeable
---
 .../java/org/apache/empire/commons/ClassUtils.java | 40 +++++++++
 .../main/java/org/apache/empire/db/DBReader.java   | 94 +++++++---------------
 .../main/java/org/apache/empire/db/DBRowSet.java   | 32 ++------
 .../main/java/org/apache/empire/db/DBTable.java    | 36 +++++++++
 4 files changed, 109 insertions(+), 93 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
index 18178ba..6d79ca5 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ClassUtils.java
@@ -23,10 +23,12 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import org.apache.commons.beanutils.ConstructorUtils;
 import org.apache.empire.exceptions.EmpireException;
 import org.apache.empire.exceptions.InternalException;
 import org.apache.empire.exceptions.InvalidArgumentException;
@@ -179,6 +181,44 @@ public final class ClassUtils
             throw new InternalException(e);
         }
     }
+
+    /**
+     * copied from org.apache.commons.beanutils.ConstructorUtils since it's private there
+     */
+    public static Constructor<?> findMatchingAccessibleConstructor(Class<?> clazz, Class<?>[] parameterTypes)
+    {
+        // search through all constructors 
+        int paramSize = parameterTypes.length;
+        Constructor<?>[] ctors = clazz.getConstructors();
+        for (int i = 0, size = ctors.length; i < size; i++)
+        {   // compare parameters
+            Class<?>[] ctorParams = ctors[i].getParameterTypes();
+            int ctorParamSize = ctorParams.length;
+            if (ctorParamSize == paramSize)
+            {   // Param Size matches
+                boolean match = true;
+                for (int n = 0; n < ctorParamSize; n++)
+                {
+                    if (!ObjectUtils.isAssignmentCompatible(ctorParams[n], parameterTypes[n]))
+                    {
+                        match = false;
+                        break;
+                    }
+                }
+                if (match) {
+                    // get accessible version of method
+                    Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(ctors[i]);
+                    if (ctor != null) {
+                        try {
+                            ctor.setAccessible(true);
+                        } catch (SecurityException se) { /* ignore */ }
+                        return ctor;
+                    }
+                }
+            }
+        }
+        return null;
+    }
     
     /**
      * Invoke a simple method (without parameters) on an object using reflection
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBReader.java b/empire-db/src/main/java/org/apache/empire/db/DBReader.java
index 2a3cca6..12f89bb 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBReader.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBReader.java
@@ -18,6 +18,7 @@
  */
 package org.apache.empire.db;
 
+import java.io.Closeable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.sql.Connection;
@@ -31,7 +32,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.beanutils.ConstructorUtils;
+import org.apache.empire.commons.ClassUtils;
 import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.data.ColumnExpr;
 import org.apache.empire.data.DataType;
@@ -41,8 +42,8 @@ import org.apache.empire.db.exceptions.QueryNoResultException;
 import org.apache.empire.db.expr.join.DBJoinExpr;
 import org.apache.empire.exceptions.BeanInstantiationException;
 import org.apache.empire.exceptions.InvalidArgumentException;
-import org.apache.empire.exceptions.UnspecifiedErrorException;
 import org.apache.empire.exceptions.ObjectNotValidException;
+import org.apache.empire.exceptions.UnspecifiedErrorException;
 import org.apache.empire.xml.XMLUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -72,7 +73,7 @@ import org.w3c.dom.Element;
  *
  *
  */
-public class DBReader extends DBRecordData implements DBContextAware
+public class DBReader extends DBRecordData implements DBContextAware, Closeable
 {
     // *Deprecated* private static final long serialVersionUID = 1L;
   
@@ -509,13 +510,12 @@ public class DBReader extends DBRecordData implements DBContextAware
         try
         { // Dispose iterator
             if (iterator != null)
-            {
-                iterator.dispose();
+            {   iterator.dispose();
                 iterator = null;
             }
-            // Close Recordset
+            // Close JDBC-Resultset
             if (rset != null)
-            {
+            {   // call driver
                 context.getDriver().closeResultSet(rset);
                 // remove from tracking-list
                 endTrackingThisResultSet();
@@ -659,7 +659,7 @@ public class DBReader extends DBRecordData implements DBContextAware
         DBRowSet rowset = rec.getRowSet();
     	rowset.initRecord(rec, this, null);
     }
-
+    
     /**
      * Returns the result of a query as a list of objects restricted
      * to a maximum number of objects (unless maxCount is -1).
@@ -680,21 +680,16 @@ public class DBReader extends DBRecordData implements DBContextAware
         }
         // Query List
         try
-        {
-            // Check whether we can use a constructor
-            Class<?>[] paramTypes = new Class[getFieldCount()];
-            for (int i = 0; i < colList.length; i++)
-                paramTypes[i] = DBExpr.getValueClass(colList[i].getDataType()); 
-            // Find Constructor
-            Constructor<?> ctor = findMatchingAccessibleConstructor(t, paramTypes);
+        {   // Find Constructor
+            Constructor<?> ctor = findBeanConstructor(t);
             Object[] args = (ctor!=null) ? new Object[getFieldCount()] : null; 
+            Class<?>[] ctorParamTypes = (ctor!=null) ? ctor.getParameterTypes() : null;
             
             // Create a list of beans
             while (moveNext() && maxCount != 0)
             { // Create bean an init
                 if (ctor!=null)
                 {   // Use Constructor
-                    Class<?>[] ctorParamTypes = ctor.getParameterTypes();
                     for (int i = 0; i < getFieldCount(); i++)
                         args[i] = ObjectUtils.convert(ctorParamTypes[i], getValue(i));
                     T bean = (T)ctor.newInstance(args);
@@ -983,6 +978,23 @@ public class DBReader extends DBRecordData implements DBContextAware
     }
 
     /**
+     * Returns a constructor for a bean class for the set of parameters or null if no suitable constructor is found
+     * @param clazz the bean class
+     * @param parameterTypes
+     * @return a constructor for the readers columns or null if not suitable constructor is available
+     */
+    protected Constructor<?> findBeanConstructor(Class<?> beanClass)
+    {
+        // Check whether we can use a constructor
+        Class<?>[] paramTypes = new Class[getFieldCount()];
+        for (int i = 0; i < colList.length; i++)
+            paramTypes[i] = DBExpr.getValueClass(colList[i].getDataType()); 
+        // Find Constructor
+        Constructor<?> ctor = ClassUtils.findMatchingAccessibleConstructor(beanClass, paramTypes);
+        return ctor;
+    }
+
+    /**
      * Support for finding code errors where a DBRecordSet is opened but not closed.
      * 
      * @author bond
@@ -1034,56 +1046,6 @@ public class DBReader extends DBRecordData implements DBContextAware
     }
 
     /**
-     * copied from org.apache.commons.beanutils.ConstructorUtils since it's private there
-     */
-    protected static Constructor<?> findMatchingAccessibleConstructor(Class<?> clazz, Class<?>[] parameterTypes)
-    {
-        // See if we can find the method directly
-        // probably faster if it works
-        // (I am not sure whether it's a good idea to run into Exceptions)
-        // try {
-        //     Constructor ctor = clazz.getConstructor(parameterTypes);
-        //     try {
-        //         // see comment in org.apache.commons.beanutils.ConstructorUtils
-        //         ctor.setAccessible(true);
-        //     } catch (SecurityException se) { /* ignore */ }
-        //     return ctor;
-        // } catch (NoSuchMethodException e) { /* SWALLOW */ }
-
-        // search through all constructors 
-        int paramSize = parameterTypes.length;
-        Constructor<?>[] ctors = clazz.getConstructors();
-        for (int i = 0, size = ctors.length; i < size; i++)
-        {   // compare parameters
-            Class<?>[] ctorParams = ctors[i].getParameterTypes();
-            int ctorParamSize = ctorParams.length;
-            if (ctorParamSize == paramSize)
-            {   // Param Size matches
-                boolean match = true;
-                for (int n = 0; n < ctorParamSize; n++)
-                {
-                    if (!ObjectUtils.isAssignmentCompatible(ctorParams[n], parameterTypes[n]))
-                    {
-                        match = false;
-                        break;
-                    }
-                }
-                if (match) {
-                    // get accessible version of method
-                    Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(ctors[i]);
-                    if (ctor != null) {
-                        try {
-                            ctor.setAccessible(true);
-                        } catch (SecurityException se) { /* ignore */ }
-                        return ctor;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * Enables or disabled tracking of open ResultSets
      * @param enable true to enable or false otherwise
      * @return the previous state of the trackOpenResultSets
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index 05e14cc..ed00ed9 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -607,33 +607,11 @@ public abstract class DBRowSet extends DBExpr
      */
     protected void initRecordDefaultValues(DBRecord rec, Connection conn)
     {
-        Object[] fields = rec.getFields();
-        /*
-         *  Connection Auto-Detect (disabled!)
-         *  Use derived class to add connection if necessary
-         *         
-        DBColumn pkColumn = (primaryKey!=null ? primaryKey.getColumn(0) : null);
-        if (conn==null && pkColumn!=null && pkColumn.isAutoGenerated() && fields[getColumnIndex(pkColumn)]==null)
-        {   // Init AutoGenerated Key
-            conn = rec.getContext().getConnection();
-        }
-        */
-        // Set Default values
-        for (int i = 0; i < fields.length; i++)
-        {   // already set ?
-            if (fields[i]!=null)
-                continue; 
-            // check default
-            DBColumn column = columns.get(i);
-            if (column instanceof DBTableColumn)
-            {   // getDefaultValue
-                Object value = ((DBTableColumn)column).getRecordDefaultValue(conn);
-                if (value==null)
-                    continue;
-                // Initial value
-                fields[i] = value;
-            }
-        }
+        /* 
+         * Implemented in DBTable
+         * 
+         * Not useful for Views and Queries
+         */
     }
     
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index d3bdb86..bc02b5a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -729,4 +729,40 @@ public class DBTable extends DBRowSet implements Cloneable
     {
         return db.validateValue(column, value);
     }
+    
+    /**
+     * initializes the Record Default Values
+     * @param rec the record
+     * @param conn (optional) to allow the driver handle autogenerated fields
+     */
+    @Override
+    protected void initRecordDefaultValues(DBRecord rec, Connection conn)
+    {
+        Object[] fields = rec.getFields();
+        /*
+         *  Connection Auto-Detect (disabled!)
+         *  Use derived class to add connection if necessary
+         *         
+        DBColumn pkColumn = (primaryKey!=null ? primaryKey.getColumn(0) : null);
+        if (conn==null && pkColumn!=null && pkColumn.isAutoGenerated() && fields[getColumnIndex(pkColumn)]==null)
+        {   // Init AutoGenerated Key
+            conn = rec.getContext().getConnection();
+        }
+        */
+        // Set Default values
+        for (int i = 0; i < fields.length; i++)
+        {   // already set ?
+            if (fields[i]!=null)
+                continue; 
+            // check default
+            DBColumn column = columns.get(i);
+            // getDefaultValue
+            Object value = ((DBTableColumn)column).getRecordDefaultValue(conn);
+            if (value==null)
+                continue;
+            // Initial value
+            fields[i] = value;
+        }
+    }
+    
 }
\ No newline at end of file