You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2019/09/03 16:07:41 UTC

[groovy] branch GROOVY-9229 created (now f953a14)

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

emilles pushed a change to branch GROOVY-9229
in repository https://gitbox.apache.org/repos/asf/groovy.git.


      at f953a14  GROOVY-9229, GROOVY-9233: added missing closure parameter metadata

This branch includes the following new commits:

     new f953a14  GROOVY-9229, GROOVY-9233: added missing closure parameter metadata

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[groovy] 01/01: GROOVY-9229, GROOVY-9233: added missing closure parameter metadata

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-9229
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit f953a142982d23e655b6f2291296df4918501800
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 3 11:07:22 2019 -0500

    GROOVY-9229, GROOVY-9233: added missing closure parameter metadata
---
 .../groovy-sql/src/main/java/groovy/sql/Sql.java   | 224 +++++++++++----------
 1 file changed, 114 insertions(+), 110 deletions(-)

diff --git a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
index 52589c5..e7e45dc 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
@@ -28,6 +28,7 @@ import groovy.transform.stc.SimpleType;
 import org.codehaus.groovy.runtime.InvokerHelper;
 
 import javax.sql.DataSource;
+
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
@@ -133,7 +134,7 @@ import static org.apache.groovy.sql.extensions.SqlExtensions.toRowResult;
  * [ID:20, NAME:Grails, URL:http://grails.org]
  * [ID:40, NAME:Gradle, URL:http://gradle.org]
  * </pre>
- * Also, <code>eachRow</code> and <code>rows</code> support paging.  Here's an example: 
+ * Also, <code>eachRow</code> and <code>rows</code> support paging.  Here's an example:
  * <pre>
  * sql.eachRow('select * from PROJECT', 2, 2) { row {@code ->}
  *     println "${row.name.padRight(10)} ($row.url)"
@@ -144,7 +145,7 @@ import static org.apache.groovy.sql.extensions.SqlExtensions.toRowResult;
  * Grails     (http://grails.org)
  * Griffon    (http://griffon.codehaus.org)
  * </pre>
- * 
+ *
  * Finally, we should clean up:
  * <pre>
  * sql.close()
@@ -294,7 +295,7 @@ public class Sql implements AutoCloseable {
      * @see #newInstance(String)
      * @throws SQLException if a database access error occurs
      */
-    public static void withInstance(String url, Closure c) throws SQLException {
+    public static void withInstance(String url, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c) throws SQLException {
         try (Sql sql = newInstance(url)) {
             c.call(sql);
         }
@@ -330,7 +331,8 @@ public class Sql implements AutoCloseable {
      * @see #newInstance(String, java.util.Properties)
      * @throws SQLException if a database access error occurs
      */
-    public static void withInstance(String url, Properties properties, Closure c) throws SQLException {
+    public static void withInstance(String url, Properties properties, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c)
+            throws SQLException {
         try (Sql sql = newInstance(url, properties)) {
             c.call(sql);
         }
@@ -371,7 +373,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @throws ClassNotFoundException if the driver class cannot be found or loaded
      */
-    public static void withInstance(String url, Properties properties, String driverClassName, Closure c)
+    public static void withInstance(String url, Properties properties, String driverClassName, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c)
             throws SQLException, ClassNotFoundException {
         try (Sql sql = newInstance(url, properties, driverClassName)) {
             c.call(sql);
@@ -408,7 +410,8 @@ public class Sql implements AutoCloseable {
      * @see #newInstance(String, String, String)
      * @throws SQLException if a database access error occurs
      */
-    public static void withInstance(String url, String user, String password, Closure c) throws SQLException {
+    public static void withInstance(String url, String user, String password, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c)
+            throws SQLException {
         try (Sql sql = newInstance(url, user, password)) {
             c.call(sql);
         }
@@ -449,7 +452,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @throws ClassNotFoundException if the driver class cannot be found or loaded
      */
-    public static void withInstance(String url, String user, String password, String driverClassName, Closure c)
+    public static void withInstance(String url, String user, String password, String driverClassName, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c)
             throws SQLException, ClassNotFoundException {
         try (Sql sql = newInstance(url, user, password, driverClassName)) {
             c.call(sql);
@@ -484,7 +487,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @throws ClassNotFoundException if the driver class cannot be found or loaded
      */
-    public static void withInstance(String url, String driverClassName, Closure c)
+    public static void withInstance(String url, String driverClassName, @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql") Closure c)
             throws SQLException, ClassNotFoundException {
         try (Sql sql = newInstance(url, driverClassName)) {
             c.call(sql);
@@ -523,7 +526,7 @@ public class Sql implements AutoCloseable {
      *     resultSetConcurrency: CONCUR_READ_ONLY
      * )
      * </pre>
-     * 
+     *
      * @param args a Map contain further arguments
      * @return a new Sql instance with a connection
      * @throws SQLException           if a database access error occurs
@@ -632,7 +635,9 @@ public class Sql implements AutoCloseable {
             // readonly Map otherwise seen as Map<String, Serializable>
             @NamedParam(value = "unused", type = Object.class)
             Map<String, Object> args,
-            Closure c) throws SQLException, ClassNotFoundException {
+            @ClosureParams(value=SimpleType.class, options="groovy.sql.Sql")
+            Closure c)
+                throws SQLException, ClassNotFoundException {
         try (Sql sql = newInstance(args)) {
             c.call(sql);
         }
@@ -1696,7 +1701,6 @@ public class Sql implements AutoCloseable {
         return rows(sql, offset, maxRows, null);
     }
 
-
     /**
      * Performs the given SQL query and return the rows of the result set.
      * In addition, the <code>metaClosure</code> will be called once passing in the
@@ -2363,7 +2367,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @since 2.3.2
      */
-    public void execute(String sql, Closure processResults) throws SQLException {
+    public void execute(String sql, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List<groovy.sql.GroovyRowResult>", "boolean,int"}) Closure processResults) throws SQLException {
         Connection connection = createConnection();
         Statement statement = null;
         try {
@@ -2450,7 +2454,7 @@ public class Sql implements AutoCloseable {
      * @see #execute(String, Closure)
      * @since 2.3.2
      */
-    public void execute(String sql, List<Object> params, Closure processResults) throws SQLException {
+    public void execute(String sql, List<Object> params, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List<groovy.sql.GroovyRowResult>", "boolean,int"}) Closure processResults) throws SQLException {
         Connection connection = createConnection();
         PreparedStatement statement = null;
         try {
@@ -2507,7 +2511,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @since 2.3.2
      */
-    public void execute(Map params, String sql, Closure processResults) throws SQLException {
+    public void execute(Map params, String sql, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List<groovy.sql.GroovyRowResult>", "boolean,int"}) Closure processResults) throws SQLException {
         execute(sql, singletonList(params), processResults);
     }
 
@@ -2547,7 +2551,7 @@ public class Sql implements AutoCloseable {
      * @see #execute(String, List, Closure)
      * @since 2.3.2
      */
-    public void execute(String sql, Object[] params, Closure processResults) throws SQLException {
+    public void execute(String sql, Object[] params, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List<groovy.sql.GroovyRowResult>", "boolean,int"}) Closure processResults) throws SQLException {
         execute(sql, Arrays.asList(params), processResults);
     }
 
@@ -2593,7 +2597,7 @@ public class Sql implements AutoCloseable {
      * @see #execute(String, List, Closure)
      * @since 2.3.2
      */
-    public void execute(GString gstring, Closure processResults) throws SQLException {
+    public void execute(GString gstring, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List<groovy.sql.GroovyRowResult>", "boolean,int"}) Closure processResults) throws SQLException {
         List<Object> params = getParameters(gstring);
         String sql = asSql(gstring, params);
         execute(sql, params, processResults);
@@ -3165,7 +3169,7 @@ public class Sql implements AutoCloseable {
      * @param closure called for each row with a GroovyResultSet
      * @throws SQLException if a database access error occurs
      */
-    public void call(String sql, List<Object> params, Closure closure) throws Exception {
+    public void call(String sql, List<Object> params, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws Exception {
         callWithRows(sql, params, NO_RESULT_SETS, closure);
     }
 
@@ -3202,7 +3206,7 @@ public class Sql implements AutoCloseable {
      * @see #call(String, List, Closure)
      * @see #expand(Object)
      */
-    public void call(GString gstring, Closure closure) throws Exception {
+    public void call(GString gstring, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws Exception {
         List<Object> params = getParameters(gstring);
         String sql = asSql(gstring, params);
         call(sql, params, closure);
@@ -3233,7 +3237,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @see #callWithRows(String, List, Closure)
      */
-    public List<GroovyRowResult> callWithRows(GString gstring, Closure closure) throws SQLException {
+    public List<GroovyRowResult> callWithRows(GString gstring, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException {
         List<Object> params = getParameters(gstring);
         String sql = asSql(gstring, params);
         return callWithRows(sql, params, closure);
@@ -3263,7 +3267,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @see #callWithRows(GString, Closure)
      */
-    public List<GroovyRowResult> callWithRows(String sql, List<Object> params, Closure closure) throws SQLException {
+    public List<GroovyRowResult> callWithRows(String sql, List<Object> params, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException {
         return callWithRows(sql, params, FIRST_RESULT_SET, closure).get(0);
     }
 
@@ -3292,7 +3296,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @see #callWithAllRows(String, List, Closure)
      */
-    public List<List<GroovyRowResult>> callWithAllRows(GString gstring, Closure closure) throws SQLException {
+    public List<List<GroovyRowResult>> callWithAllRows(GString gstring, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException {
         List<Object> params = getParameters(gstring);
         String sql = asSql(gstring, params);
         return callWithAllRows(sql, params, closure);
@@ -3322,92 +3326,11 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database access error occurs
      * @see #callWithRows(GString, Closure)
      */
-    public List<List<GroovyRowResult>> callWithAllRows(String sql, List<Object> params, Closure closure) throws SQLException {
+    public List<List<GroovyRowResult>> callWithAllRows(String sql, List<Object> params, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException {
         return callWithRows(sql, params, ALL_RESULT_SETS, closure);
     }
 
     /**
-     * Base internal method for call(), callWithRows(), and callWithAllRows() style of methods.
-     * <p>
-     * Performs a stored procedure call with the given parameters,
-     * calling the closure once with all result objects,
-     * and also returning the rows of the ResultSet(s) (if processResultSets is set to
-     * Sql.FIRST_RESULT_SET, Sql.ALL_RESULT_SETS)
-     * <p>
-     * Main purpose of processResultSets param is to retain original call() method
-     * performance when this is set to Sql.NO_RESULT_SETS
-     * <p>
-     * Resource handling is performed automatically where appropriate.
-     *
-     * @param sql     the sql statement
-     * @param params  a list of parameters
-     * @param processResultsSets the result sets to process, either Sql.NO_RESULT_SETS, Sql.FIRST_RESULT_SET, or Sql.ALL_RESULT_SETS
-     * @param closure called once with all out parameter results
-     * @return a list of GroovyRowResult objects
-     * @throws SQLException if a database access error occurs
-     * @see #callWithRows(String, List, Closure)
-     */
-    protected List<List<GroovyRowResult>> callWithRows(String sql, List<Object> params, int processResultsSets, Closure closure) throws SQLException {
-        Connection connection = createConnection();
-        CallableStatement statement = null;
-        List<GroovyResultSet> resultSetResources = new ArrayList<GroovyResultSet>();
-        try {
-            statement = getCallableStatement(connection, sql, params);
-            boolean hasResultSet = statement.execute();
-            List<Object> results = new ArrayList<Object>();
-            int indx = 0;
-            int inouts = 0;
-            for (Object value : params) {
-                if (value instanceof OutParameter) {
-                    if (value instanceof ResultSetOutParameter) {
-                        GroovyResultSet resultSet = CallResultSet.getImpl(statement, indx);
-                        resultSetResources.add(resultSet);
-                        results.add(resultSet);
-                    } else {
-                        Object o = statement.getObject(indx + 1);
-                        if (o instanceof ResultSet) {
-                            GroovyResultSet resultSet = new GroovyResultSetProxy((ResultSet) o).getImpl();
-                            results.add(resultSet);
-                            resultSetResources.add(resultSet);
-                        } else {
-                            results.add(o);
-                        }
-                    }
-                    inouts++;
-                }
-                indx++;
-            }
-            closure.call(results.toArray(new Object[inouts]));
-            List<List<GroovyRowResult>> resultSets = new ArrayList<List<GroovyRowResult>>();
-            if (processResultsSets == NO_RESULT_SETS) {
-                resultSets.add(new ArrayList<GroovyRowResult>());
-                return resultSets;
-            }
-            //Check both hasResultSet and getMoreResults() because of differences in vendor behavior
-            if (!hasResultSet) {
-                hasResultSet = statement.getMoreResults();
-            }
-            while (hasResultSet && (processResultsSets != NO_RESULT_SETS)) {
-                resultSets.add(asList(sql, statement.getResultSet()));
-                if (processResultsSets == FIRST_RESULT_SET) {
-                    break;
-                } else {
-                    hasResultSet = statement.getMoreResults();
-                }
-            }
-            return resultSets;
-        } catch (SQLException e) {
-            LOG.warning("Failed to execute: " + sql + " because: " + e.getMessage());
-            throw e;
-        } finally {
-            for (GroovyResultSet rs : resultSetResources) {
-                closeResources(null, null, rs);
-            }
-            closeResources(connection, statement);
-        }
-    }
-
-    /**
      * If this SQL object was created with a Connection then this method closes
      * the connection. If this SQL object was created from a DataSource then
      * this method only frees any cached objects (statements in particular).
@@ -3540,7 +3463,7 @@ public class Sql implements AutoCloseable {
      * @param closure the given closure
      * @throws SQLException if a database error occurs
      */
-    public void cacheConnection(Closure closure) throws SQLException {
+    public void cacheConnection(@ClosureParams(value=SimpleType.class, options="java.sql.Connection") Closure closure) throws SQLException {
         boolean savedCacheConnection = cacheConnection;
         cacheConnection = true;
         Connection connection = null;
@@ -3565,7 +3488,7 @@ public class Sql implements AutoCloseable {
      * @param closure the given closure
      * @throws SQLException if a database error occurs
      */
-    public void withTransaction(Closure closure) throws SQLException {
+    public void withTransaction(@ClosureParams(value=SimpleType.class, options="java.sql.Connection") Closure closure) throws SQLException {
         boolean savedCacheConnection = cacheConnection;
         cacheConnection = true;
         Connection connection = null;
@@ -3650,7 +3573,7 @@ public class Sql implements AutoCloseable {
      *                      database fails to execute properly or attempts to return a result set.
      * @see #withBatch(int, Closure)
      */
-    public int[] withBatch(Closure closure) throws SQLException {
+    public int[] withBatch(@ClosureParams(value=SimpleType.class, options="groovy.sql.BatchingStatementWrapper") Closure closure) throws SQLException {
         return withBatch(0, closure);
     }
 
@@ -3699,7 +3622,7 @@ public class Sql implements AutoCloseable {
      * @see BatchingStatementWrapper
      * @see Statement
      */
-    public int[] withBatch(int batchSize, Closure closure) throws SQLException {
+    public int[] withBatch(int batchSize, @ClosureParams(value=SimpleType.class, options="groovy.sql.BatchingStatementWrapper") Closure closure) throws SQLException {
         Connection connection = createConnection();
         BatchingStatementWrapper statement = null;
         boolean savedWithinBatch = withinBatch;
@@ -3763,7 +3686,7 @@ public class Sql implements AutoCloseable {
      * @see BatchingPreparedStatementWrapper
      * @see PreparedStatement
      */
-    public int[] withBatch(String sql, Closure closure) throws SQLException {
+    public int[] withBatch(String sql, @ClosureParams(value=SimpleType.class, options="groovy.sql.BatchingPreparedStatementWrapper") Closure closure) throws SQLException {
         return withBatch(0, sql, closure);
     }
 
@@ -3837,7 +3760,7 @@ public class Sql implements AutoCloseable {
      * @see BatchingPreparedStatementWrapper
      * @see PreparedStatement
      */
-    public int[] withBatch(int batchSize, String sql, Closure closure) throws SQLException {
+    public int[] withBatch(int batchSize, String sql, @ClosureParams(value=SimpleType.class, options="groovy.sql.BatchingPreparedStatementWrapper") Closure closure) throws SQLException {
         Connection connection = createConnection();
         List<Tuple> indexPropList = null;
         SqlWithParams preCheck = buildSqlWithIndexedProps(sql);
@@ -3878,7 +3801,7 @@ public class Sql implements AutoCloseable {
      * @throws SQLException if a database error occurs
      * @see #setCacheStatements(boolean)
      */
-    public void cacheStatements(Closure closure) throws SQLException {
+    public void cacheStatements(@ClosureParams(value=SimpleType.class, options="java.sql.Connection") Closure closure) throws SQLException {
         boolean savedCacheStatements = cacheStatements;
         cacheStatements = true;
         Connection connection = null;
@@ -3896,6 +3819,87 @@ public class Sql implements AutoCloseable {
     //-------------------------------------------------------------------------
 
     /**
+     * Base internal method for call(), callWithRows(), and callWithAllRows() style of methods.
+     * <p>
+     * Performs a stored procedure call with the given parameters,
+     * calling the closure once with all result objects,
+     * and also returning the rows of the ResultSet(s) (if processResultSets is set to
+     * Sql.FIRST_RESULT_SET, Sql.ALL_RESULT_SETS)
+     * <p>
+     * Main purpose of processResultSets param is to retain original call() method
+     * performance when this is set to Sql.NO_RESULT_SETS
+     * <p>
+     * Resource handling is performed automatically where appropriate.
+     *
+     * @param sql     the sql statement
+     * @param params  a list of parameters
+     * @param processResultsSets the result sets to process, either Sql.NO_RESULT_SETS, Sql.FIRST_RESULT_SET, or Sql.ALL_RESULT_SETS
+     * @param closure called once with all out parameter results
+     * @return a list of GroovyRowResult objects
+     * @throws SQLException if a database access error occurs
+     * @see #callWithRows(String, List, Closure)
+     */
+    protected List<List<GroovyRowResult>> callWithRows(String sql, List<Object> params, int processResultsSets, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException {
+        Connection connection = createConnection();
+        CallableStatement statement = null;
+        List<GroovyResultSet> resultSetResources = new ArrayList<GroovyResultSet>();
+        try {
+            statement = getCallableStatement(connection, sql, params);
+            boolean hasResultSet = statement.execute();
+            List<Object> results = new ArrayList<Object>();
+            int indx = 0;
+            int inouts = 0;
+            for (Object value : params) {
+                if (value instanceof OutParameter) {
+                    if (value instanceof ResultSetOutParameter) {
+                        GroovyResultSet resultSet = CallResultSet.getImpl(statement, indx);
+                        resultSetResources.add(resultSet);
+                        results.add(resultSet);
+                    } else {
+                        Object o = statement.getObject(indx + 1);
+                        if (o instanceof ResultSet) {
+                            GroovyResultSet resultSet = new GroovyResultSetProxy((ResultSet) o).getImpl();
+                            results.add(resultSet);
+                            resultSetResources.add(resultSet);
+                        } else {
+                            results.add(o);
+                        }
+                    }
+                    inouts++;
+                }
+                indx++;
+            }
+            closure.call(results.toArray(new Object[inouts]));
+            List<List<GroovyRowResult>> resultSets = new ArrayList<List<GroovyRowResult>>();
+            if (processResultsSets == NO_RESULT_SETS) {
+                resultSets.add(new ArrayList<GroovyRowResult>());
+                return resultSets;
+            }
+            //Check both hasResultSet and getMoreResults() because of differences in vendor behavior
+            if (!hasResultSet) {
+                hasResultSet = statement.getMoreResults();
+            }
+            while (hasResultSet && (processResultsSets != NO_RESULT_SETS)) {
+                resultSets.add(asList(sql, statement.getResultSet()));
+                if (processResultsSets == FIRST_RESULT_SET) {
+                    break;
+                } else {
+                    hasResultSet = statement.getMoreResults();
+                }
+            }
+            return resultSets;
+        } catch (SQLException e) {
+            LOG.warning("Failed to execute: " + sql + " because: " + e.getMessage());
+            throw e;
+        } finally {
+            for (GroovyResultSet rs : resultSetResources) {
+                closeResources(null, null, rs);
+            }
+            closeResources(connection, statement);
+        }
+    }
+
+    /**
      * Useful helper method which handles resource management when executing a
      * query which returns a result set.
      * Derived classes of Sql can override "createQueryCommand" and then call