Index: src/main/groovy/sql/Sql.java =================================================================== RCS file: /home/projects/groovy/scm/groovy/groovy-core/src/main/groovy/sql/Sql.java,v retrieving revision 1.20 diff -u -r1.20 Sql.java --- src/main/groovy/sql/Sql.java 9 Apr 2006 15:16:53 -0000 1.20 +++ src/main/groovy/sql/Sql.java 30 Apr 2006 20:52:13 -0000 @@ -636,6 +636,53 @@ } /** + * Executes the given SQL statement. See {@link #executeInsert(GString)} + * for more details. + * @param sql The SQL statement to execute. + * @return A list of the auto-generated column values for each + * inserted row. + */ + public List executeInsert(String sql) throws SQLException { + Connection connection = createConnection(); + Statement statement = null; + try { + log.fine(sql); + statement = connection.createStatement(); + configure(statement); + boolean hasResultSet = statement.execute(sql, Statement.RETURN_GENERATED_KEYS); + + // Prepare a list to contain the auto-generated column + // values, and then fetch them from the statement. + List autoKeys = new ArrayList(); + ResultSet keys = statement.getGeneratedKeys(); + int count = keys.getMetaData().getColumnCount(); + + // Copy the column values into a list of a list. + while (keys.next()) { + List rowKeys = new ArrayList(count); + for (int i = 1; i <= count; i++) { + rowKeys.add(keys.getObject(i)); + } + + autoKeys.add(rowKeys); + } + + // Store the update count so that it can be retrieved by + // clients, and then return the list of auto-generated + // values. + this.updateCount = statement.getUpdateCount(); + return autoKeys; + } + catch (SQLException e) { + log.log(Level.FINE, "Failed to execute: " + sql, e); + throw e; + } + finally { + closeResources(connection, statement); + } + } + + /** * Executes the given piece of SQL with parameters */ public boolean execute(String sql, List params) throws SQLException { @@ -685,6 +732,60 @@ } /** + * Executes the given SQL statement with a particular list of + * parameter values. See {@link #executeInsert(GString)} for + * more details. + * @param sql The SQL statement to execute. + * @param params The parameter values that will be substituted + * into the SQL statement's parameter slots. + * @return A list of the auto-generated column values for each + * inserted row. + */ + public List executeInsert(String sql, List params) throws SQLException { + // Now send the SQL to the database. + Connection connection = createConnection(); + PreparedStatement statement = null; + try { + log.fine(sql); + + // Prepare a statement for the SQL and then execute it. + statement = connection.prepareStatement(sql); + setParameters(params, statement); + configure(statement); + boolean hasResultSet = statement.execute(sql, Statement.RETURN_GENERATED_KEYS); + + // Prepare a list to contain the auto-generated column + // values, and then fetch them from the statement. + List autoKeys = new ArrayList(); + ResultSet keys = statement.getGeneratedKeys(); + int count = keys.getMetaData().getColumnCount(); + + // Copy the column values into a list of a list. + while (keys.next()) { + List rowKeys = new ArrayList(count); + for (int i = 1; i <= count; i++) { + rowKeys.add(keys.getObject(i)); + } + + autoKeys.add(rowKeys); + } + + // Store the update count so that it can be retrieved by + // clients, and then return the list of auto-generated + // values. + this.updateCount = statement.getUpdateCount(); + return autoKeys; + } + catch (SQLException e) { + log.log(Level.FINE, "Failed to execute: " + sql, e); + throw e; + } + finally { + closeResources(connection, statement); + } + } + + /** * Executes the given SQL with embedded expressions inside */ public boolean execute(GString gstring) throws SQLException { @@ -702,6 +803,44 @@ List params = getParameters(gstring); String sql = asSql(gstring, params); return executeUpdate(sql, params); + } + + /** + *
Executes the given SQL with embedded expressions inside, and
+ * returns the values of any auto-generated colums, such as an
+ * autoincrement ID field. These values can be accessed using
+ * array notation. For example, to return the second auto-generated
+ * column value of the third row, use keys[3][1]. The
+ * method is designed to be used with SQL INSERT statements, but is
+ * not limited to them.
The standard use for this method is when a table has an + * autoincrement ID column and you want to know what the ID is for + * a newly inserted row. In this example, we insert a single row + * into a table in which the first column contains the autoincrement + * ID:
+ *
+ * def sql = Sql.newInstance("jdbc:mysql://localhost:3306/groovy",
+ * "user",
+ * "password",
+ * "com.mysql.jdbc.Driver")
+ *
+ * def keys = sql.insert("insert into test_table (INT_DATA, STRING_DATA) "
+ * + "VALUES (1, 'Key Largo')")
+ *
+ * def id = keys[0][0]
+ *
+ * // 'id' now contains the value of the new row's ID column.
+ * // It can be used to update an object representation's
+ * // id attribute for example.
+ * ...
+ *
+ * @return A list of column values representing each row's
+ * auto-generated keys.
+ */
+ public List executeInsert(GString gstring) throws SQLException {
+ List params = getParameters(gstring);
+ String sql = asSql(gstring, params);
+ return executeInsert(sql, params);
}
/**