Repository: incubator-groovy Updated Branches: refs/heads/master d854f6809 -> 46b59e305
groovy-sql: doco for named and named-ordinal placeholders Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/46b59e30 Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/46b59e30 Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/46b59e30 Branch: refs/heads/master Commit: 46b59e30588671946348d2bf3f0df51b3020023f Parents: d854f68 Author: Paul King <[email protected]> Authored: Sat Apr 18 12:01:24 2015 +1000 Committer: Paul King <[email protected]> Committed: Sat Apr 18 12:01:24 2015 +1000 ---------------------------------------------------------------------- .../groovy-sql/src/spec/doc/sql-userguide.adoc | 35 +++++++++++++++++- .../groovy-sql/src/spec/test/SqlTest.groovy | 38 ++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/46b59e30/subprojects/groovy-sql/src/spec/doc/sql-userguide.adoc ---------------------------------------------------------------------- diff --git a/subprojects/groovy-sql/src/spec/doc/sql-userguide.adoc b/subprojects/groovy-sql/src/spec/doc/sql-userguide.adoc index 5d06fd8..ba2f11d 100644 --- a/subprojects/groovy-sql/src/spec/doc/sql-userguide.adoc +++ b/subprojects/groovy-sql/src/spec/doc/sql-userguide.adoc @@ -277,7 +277,40 @@ Consult the JavaDoc for your driver to find out what metadata information is ava === Named and named-ordinal parameters -(TBD) +Groovy supports some additional alternative placeholder syntax variants. The GString variants +are typically preferred over these alternatives but the alternatives are useful for Java integration +purposes and sometimes in templating scenarios where GStrings might already be in heavy use as part +of a template. The named parameter variants are much like the String plus list of parameter variants but +instead of having a list of `?` placeholders followed by a list of parameters, you have one or more +placeholders having the form `:propName` or `?.propName` and a single map, named arguments or a +domain object as the parameter. The map or domain object should have a property named `propName` +corresponding to each supplied placeholder. + +Here is an example using the colon form: + +[source,groovy] +.Named parameters (colon form) +---- +include::{rootProjectDir}/subprojects/groovy-sql/src/spec/test/SqlTest.groovy[tags=sql_named,indent=0] +---- + +And another example using the question mark form: + +[source,groovy] +.Named parameters (question mark form) +---- +include::{rootProjectDir}/subprojects/groovy-sql/src/spec/test/SqlTest.groovy[tags=sql_named2,indent=0] +---- + +If the information you need to supply is spread across multiple maps or domain objects you can +use the question mark form with an additional ordinal index as shown here: + +[source,groovy] +.Named-ordinal parameters +---- +include::{rootProjectDir}/subprojects/groovy-sql/src/spec/test/SqlTest.groovy[tags=sql_named_ordinal1,indent=0] +include::{rootProjectDir}/subprojects/groovy-sql/src/spec/test/SqlTest.groovy[tags=sql_named_ordinal2,indent=0] +---- === Stored procedures http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/46b59e30/subprojects/groovy-sql/src/spec/test/SqlTest.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-sql/src/spec/test/SqlTest.groovy b/subprojects/groovy-sql/src/spec/test/SqlTest.groovy index 22d087f..21d3959 100644 --- a/subprojects/groovy-sql/src/spec/test/SqlTest.groovy +++ b/subprojects/groovy-sql/src/spec/test/SqlTest.groovy @@ -344,6 +344,44 @@ class SqlTest extends GroovyTestCase { ''' } + void testNamedOrdinal() { + assertScript ''' + import groovy.sql.Sql + + def url = 'jdbc:hsqldb:mem:yourDB' + def user = 'sa' + def password = '' + def driver = 'org.hsqldb.jdbcDriver' + // tag::sql_named_ordinal1[] + class Rockstar { String first, last } + // end::sql_named_ordinal1[] + Sql.withInstance(url, user, password, driver) { sql -> + sql.execute """ + DROP TABLE Author IF EXISTS + """ + sql.execute """ + CREATE TABLE Author ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY, + firstname VARCHAR(64), + lastname VARCHAR(64) + ) + """ + // tag::sql_named[] + sql.execute "INSERT INTO Author (firstname, lastname) VALUES (:first, :last)", first: 'Dierk', last: 'Koenig' + // end::sql_named[] + // tag::sql_named2[] + sql.execute "INSERT INTO Author (firstname, lastname) VALUES (?.first, ?.last)", first: 'Jon', last: 'Skeet' + // end::sql_named2[] + // tag::sql_named_ordinal2[] + def pogo = new Rockstar(first: 'Paul', last: 'McCartney') + def map = [lion: 'King'] + sql.execute "INSERT INTO Author (firstname, lastname) VALUES (?1.first, ?2.lion)", pogo, map + // end::sql_named_ordinal2[] + assert sql.firstRow('SELECT COUNT(*) as num FROM Author').num == 3 + } + ''' + } + void testDeletingRows() { assertScript ''' import groovy.sql.Sql
