From 1f1683468b6805b3dbceaf8dd3831e2895465a6a Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 10 Jun 2020 16:00:02 -0700 Subject: [PATCH] Update documentation on named bind parameters. I wasn't able to find documentation of these in the godoc, so I added it. Also, the README had out-of-date information. It said named bind parameters were only supported for Select, but they are also supported for Exec since 2015 (04b2c714). The documentation for ExpandSlices was embedded in the DbMap type, which made it hard to read on godoc - the entire documentation was in one large `pre` block. I moved it up to the package level docs. --- README.md | 5 ++-- db.go | 48 +--------------------------------- doc.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 8a4fb987..19f17a88 100644 --- a/README.md +++ b/README.md @@ -475,8 +475,9 @@ s, err := dbmap.SelectStr("select name from foo where blah=?", blahVal) #### Named bind parameters -You may use a map or struct to bind parameters by name. This is currently -only supported in SELECT queries. +You may use a map or struct to bind parameters by name. This is supported in +the Exec and Select* functions on DbMap and Transaction. It is not supported by +Prepare, Query, or QueryRow. ```go _, err := dbm.Select(&dest, "select * from Foo where name = :name and age = :age", map[string]interface{}{ diff --git a/db.go b/db.go index d78062e5..2cd63372 100644 --- a/db.go +++ b/db.go @@ -40,53 +40,7 @@ type DbMap struct { // ExpandSlices when enabled will convert slice arguments in mappers into flat // values. It will modify the query, adding more placeholders, and the mapper, - // adding each item of the slice as a new unique entry in the mapper. For - // example, given the scenario bellow: - // - // dbmap.Select(&output, "SELECT 1 FROM example WHERE id IN (:IDs)", map[string]interface{}{ - // "IDs": []int64{1, 2, 3}, - // }) - // - // The executed query would be: - // - // SELECT 1 FROM example WHERE id IN (:IDs0,:IDs1,:IDs2) - // - // With the mapper: - // - // map[string]interface{}{ - // "IDs": []int64{1, 2, 3}, - // "IDs0": int64(1), - // "IDs1": int64(2), - // "IDs2": int64(3), - // } - // - // It is also flexible for custom slice types. The value just need to - // implement stringer or numberer interfaces. - // - // type CustomValue string - // - // const ( - // CustomValueHey CustomValue = "hey" - // CustomValueOh CustomValue = "oh" - // ) - // - // type CustomValues []CustomValue - // - // func (c CustomValues) ToStringSlice() []string { - // values := make([]string, len(c)) - // for i := range c { - // values[i] = string(c[i]) - // } - // return values - // } - // - // func query() { - // // ... - // result, err := dbmap.Select(&output, "SELECT 1 FROM example WHERE value IN (:Values)", map[string]interface{}{ - // "Values": CustomValues([]CustomValue{CustomValueHey}), - // }) - // // ... - // } + // adding each item of the slice as a new unique entry in the mapper. ExpandSliceArgs bool tables []*TableMap diff --git a/doc.go b/doc.go index 593f1c3c..ee3e6637 100644 --- a/doc.go +++ b/doc.go @@ -6,6 +6,82 @@ // SQL databases. It uses the database/sql package, and should work with any // compliant database/sql driver. // -// Source code and project home: +// Source code, additional documentation, and examples: // https://github.com/go-gorp/gorp +// +// Query Parameters +// +// Gorp's Exec, Select*, Query, and QueryRow methods accept placeholder +// parameters in the query, to be filled from the args parameters to these +// functions. Gorp supports some additional styles for placeholder parameters: +// +// Named Bind Parameters +// +// For the Exec and Select* methods on DbMap and Transaction, Gorp supports +// named bind parameters. To use named bind parameters, instead of a list of +// parameters, pass a single `map[string]interface{}` to these functions. And +// instead of using ? in the query, use placeholder parameters of the form :word. +// Before running the query, Gorp will bind each named placeholder parameter to the +// corresponding value found by looking up "word" in the map. +// +// Example: +// +// _, err := dbm.Select(&dest, "select * from Foo where name = :name and age = :age", +// map[string]interface{}{ +// "name": "Rob", +// "age": 31, +// }) +// +// Expanding Slices +// +// If you set the ExpandSlices field of DbMap to true, placeholders that bind to +// slices will be handled specially. Gorp will modify the query, adding more +// placeholders to match the number of entries in the slice. +// +// For example, given the scenario bellow: +// +// dbmap.Select(&output, "SELECT 1 FROM example WHERE id IN (:IDs)", map[string]interface{}{ +// "IDs": []int64{1, 2, 3}, +// }) +// +// The executed query would be: +// +// SELECT 1 FROM example WHERE id IN (:IDs0,:IDs1,:IDs2) +// +// With the mapper: +// +// map[string]interface{}{ +// "IDs": []int64{1, 2, 3}, +// "IDs0": int64(1), +// "IDs1": int64(2), +// "IDs2": int64(3), +// } +// +// It is also flexible for custom slice types. The value just need to +// implement stringer or numberer interfaces. +// +// type CustomValue string +// +// const ( +// CustomValueHey CustomValue = "hey" +// CustomValueOh CustomValue = "oh" +// ) +// +// type CustomValues []CustomValue +// +// func (c CustomValues) ToStringSlice() []string { +// values := make([]string, len(c)) +// for i := range c { +// values[i] = string(c[i]) +// } +// return values +// } +// +// func query() { +// // ... +// result, err := dbmap.Select(&output, "SELECT 1 FROM example WHERE value IN (:Values)", map[string]interface{}{ +// "Values": CustomValues([]CustomValue{CustomValueHey}), +// }) +// // ... +// } package gorp