From 031133ff357a74a01c272548ec8a74485a82d4fe Mon Sep 17 00:00:00 2001 From: "@mpyw" Date: Wed, 19 Aug 2026 06:40:48 +0900 Subject: [PATCH] docs: surface typed struct parameters Build already accepts a struct (or expr.Scope), not only a map[string]any, so callers can pass parameters with Go's type checking. Make that discoverable: add a package-level Example_structParams (embedded-field promotion + qualified access) and a note in the README synopsis. Docs only; no behavior change. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01YAydPGeSHjZvJv22oz4P6d --- README.md | 5 +++++ example_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/README.md b/README.md index 2c0cd86..5a1b912 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,11 @@ templates. A string template, rather than a file, is parsed with `p.Parse` inste `bisql.ExpandFile` functions are shortcuts that construct a single-use parser from the given options. +`Build` accepts the parameters as a `map[string]any`, a **struct**, or an `expr.Scope`. Passing a +struct matches exported fields to bind names (an embedded struct's fields are promoted, and also +reachable qualified, e.g. `Filter.Status`), so parameters carry Go's type checking rather than +being untyped map values. + A `Statement` exposes the following members: | Member | Type | Description | diff --git a/example_test.go b/example_test.go index d16e26d..61f0d31 100644 --- a/example_test.go +++ b/example_test.go @@ -150,6 +150,35 @@ func Example_dialects() { // sqlserver: select id from users where name = @p1 and age >= @p2 } +// Build accepts a typed struct as well as a map[string]any, so parameters can be passed with +// Go's type checking rather than as untyped map values. Exported fields are matched to bind +// names; an embedded struct's fields are promoted (and also reachable qualified, e.g. +// Filter.Status). +func Example_structParams() { + type Filter struct { + Status string + MinAge int + } + type Params struct { + Filter + Name string + } + tmpl, _ := bisql.Parse( + "select id from users where 1 = 1" + + " and status = /*Status*/'active'" + + " and age >= /*MinAge*/0" + + " and name like /*Name*/'%x%'", + ) + stmt, _ := tmpl.Build(Params{Filter: Filter{Status: "active", MinAge: 18}, Name: "%ali%"}) + fmt.Println(stmt.SQL) + fmt.Println(stmt.Args) + fmt.Println(stmt.SQLWithArgs()) + // Output: + // select id from users where 1 = 1 and status = ? and age >= ? and name like ? + // [active 18 %ali%] + // select id from users where 1 = 1 and status = 'active' and age >= 18 and name like '%ali%' +} + // --- Function examples. --- // Parse compiles a template string into a reusable *Template.