From commits-return-9102-archive-asf-public=cust-asf.ponee.io@groovy.apache.org Mon Sep 9 23:58:07 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 66151180651 for ; Tue, 10 Sep 2019 01:58:07 +0200 (CEST) Received: (qmail 91385 invoked by uid 500); 9 Sep 2019 23:58:06 -0000 Mailing-List: contact commits-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list commits@groovy.apache.org Received: (qmail 91357 invoked by uid 99); 9 Sep 2019 23:58:06 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Sep 2019 23:58:06 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 023A381044; Mon, 9 Sep 2019 23:58:05 +0000 (UTC) Date: Mon, 09 Sep 2019 23:58:05 +0000 To: "commits@groovy.apache.org" Subject: [groovy] branch master updated: GROOVY-9229, GROOVY-9233: added missing closure parameter metadata MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <156807348567.3474.6830172056844565757@gitbox.apache.org> From: sunlan@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: groovy X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 43ca9b0a7e70b89ae1795627a02a79aed8c62de1 X-Git-Newrev: 2572c62f06621330babf0f008c1a4021242f41ef X-Git-Rev: 2572c62f06621330babf0f008c1a4021242f41ef X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/groovy.git The following commit(s) were added to refs/heads/master by this push: new 2572c62 GROOVY-9229, GROOVY-9233: added missing closure parameter metadata 2572c62 is described below commit 2572c62f06621330babf0f008c1a4021242f41ef Author: Eric Milles 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] * - * Also, eachRow and rows support paging. Here's an example: + * Also, eachRow and rows support paging. Here's an example: *
  * 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)
  * 
- * + * * Finally, we should clean up: *
  * 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
      * )
      * 
- * + * * @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 @NamedParam(value = "unused", type = Object.class) Map 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 metaClosure 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", "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 params, Closure processResults) throws SQLException { + public void execute(String sql, List params, @ClosureParams(value=SimpleType.class, options={"boolean,java.util.List", "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", "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", "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", "boolean,int"}) Closure processResults) throws SQLException { List 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 params, Closure closure) throws Exception { + public void call(String sql, List 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 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 callWithRows(GString gstring, Closure closure) throws SQLException { + public List callWithRows(GString gstring, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException { List 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 callWithRows(String sql, List params, Closure closure) throws SQLException { + public List callWithRows(String sql, List 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> callWithAllRows(GString gstring, Closure closure) throws SQLException { + public List> callWithAllRows(GString gstring, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException { List 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> callWithAllRows(String sql, List params, Closure closure) throws SQLException { + public List> callWithAllRows(String sql, List 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. - *

- * 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) - *

- * Main purpose of processResultSets param is to retain original call() method - * performance when this is set to Sql.NO_RESULT_SETS - *

- * 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> callWithRows(String sql, List params, int processResultsSets, Closure closure) throws SQLException { - Connection connection = createConnection(); - CallableStatement statement = null; - List resultSetResources = new ArrayList(); - try { - statement = getCallableStatement(connection, sql, params); - boolean hasResultSet = statement.execute(); - List results = new ArrayList(); - 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> resultSets = new ArrayList>(); - if (processResultsSets == NO_RESULT_SETS) { - resultSets.add(new ArrayList()); - 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 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. + *

+ * 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) + *

+ * Main purpose of processResultSets param is to retain original call() method + * performance when this is set to Sql.NO_RESULT_SETS + *

+ * 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> callWithRows(String sql, List params, int processResultsSets, @ClosureParams(value=SimpleType.class, options="java.lang.Object[]") Closure closure) throws SQLException { + Connection connection = createConnection(); + CallableStatement statement = null; + List resultSetResources = new ArrayList(); + try { + statement = getCallableStatement(connection, sql, params); + boolean hasResultSet = statement.execute(); + List results = new ArrayList(); + 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> resultSets = new ArrayList>(); + if (processResultsSets == NO_RESULT_SETS) { + resultSets.add(new ArrayList()); + 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