Documentation
¶
Overview ¶
Package sqlctemplate provides a way of making arbitrary text replacement in sqlc queries which normally only allow parameters which are in places valid in a prepared statement. For example, it can be used to insert a schema name as a prefix to tables referenced in sqlc, which is otherwise impossible.
Replacement is carried out from within invocations of sqlc's generated DBTX interface, after sqlc generated code runs, but before queries are executed. This is accomplished by implementing DBTX, calling Replacer.Run from within them, and injecting parameters in with WithReplacements (which is unfortunately the only way of injecting them).
Templates are modeled as SQL comments so that they're still parseable as valid SQL. An example use of the basic /* TEMPLATE ... */ syntax:
-- name: JobCountByState :one SELECT count(*) FROM /* TEMPLATE: schema */river_job WHERE state = @state;
An open/close syntax is also available for when SQL is required before processing for the query to be valid. For example, a WHERE or ORDER BY clause can't be empty, so the SQL includes a sentinel value that's parseable which is then replaced later with template values:
-- name: JobList :many SELECT * FROM river_job WHERE /* TEMPLATE_BEGIN: where_clause */ true /* TEMPLATE_END */ ORDER BY /* TEMPLATE_BEGIN: order_by_clause */ id /* TEMPLATE_END */ LIMIT @max::int;
Be careful not to place a template on a line by itself because sqlc will strip any lines that start with a comment. For example, this does NOT work:
-- name: JobList :many SELECT * FROM river_job /* TEMPLATE_BEGIN: where_clause */ LIMIT @max::int;
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WithReplacements ¶
func WithReplacements(ctx context.Context, replacements map[string]Replacement, namedArgs map[string]any) context.Context
WithReplacements adds sqlctemplate templates to the given context (they go in context because it's the only way to get them down into the innards of sqlc). namedArgs can also be passed in to replace arguments found in
If sqlctemplate params are already present in context, the two sets are merged, with the new params taking precedent.
Types ¶
type Replacement ¶
type Replacement struct {
// Stable is whether the replacement value is expected to be stable for any
// number of times Replacer.Run is called with the same given input SQL. If
// all replacements are stable, then the output of Replacer.Run is cached so
// that it doesn't have to be processed again. Replacements should be not be
// stable if they depend on input parameters.
Stable bool
// Value is the value which the template should be replaced with. For a /*
// TEMPLATE ... */ tag, replaces template and the comment containing it. For
// a /* TEMPLATE_BEGIN ... */ ... /* TEMPLATE_END */ tag pair, replaces both
// templates, comments, and the value between them.
Value string
}
Replacement defines a replacement for a template value in some input SQL.
type Replacer ¶
type Replacer struct {
// contains filtered or unexported fields
}
Replacer replaces templates with template values. As an optimization, it contains an internal cache to short circuit SQL that has entirely stable template replacements and whose output is invariant of input parameters.
The struct is written so that it's safe to use as a value and doesn't need to be initialized with a constructor. This lets it default to a usable instance on drivers that may themselves not be initialized.
func (*Replacer) Run ¶
Run replaces any tempates in input SQL with values from context added via WithReplacements.
args aren't used for replacements in the input SQL, but are needed to determine which placeholder number (e.g. $1, $2, $3, ...) we should start with to replace any template named args. The returned args value should then be used as query input as named args from context may have been added to it.
argPlaceholder is the character to use as a placeholder like "$" in "$1" or "$2". This should be a "$" for Postgres, but a "?" for SQLite.