diff --git a/mql.go b/mql.go index 02e2bdf..a6b408d 100644 --- a/mql.go +++ b/mql.go @@ -18,7 +18,8 @@ type WhereClause struct { } // Parse will parse the query and use the provided database model to create a -// where clause. Supported options: WithColumnMap, WithIgnoreFields +// where clause. Supported options: WithColumnMap, WithIgnoreFields, +// WithConverter, WithPgPlaceholder func Parse(query string, model any, opt ...Option) (*WhereClause, error) { const op = "mql.Parse" switch { @@ -40,6 +41,16 @@ func Parse(query string, model any, opt ...Option) (*WhereClause, error) { if err != nil { return nil, fmt.Errorf("%s: %w", op, err) } + opts, err := getOpts(opt...) + if err != nil { + return nil, fmt.Errorf("%s: %w", op, err) + } + if opts.withPgPlaceholder { + for i := 0; i < len(e.Args); i++ { + placeholder := fmt.Sprintf("$%d", i+1) + e.Condition = strings.Replace(e.Condition, "?", placeholder, 1) + } + } return e, nil } diff --git a/mql_test.go b/mql_test.go index f8a4fa7..b5d0fed 100644 --- a/mql_test.go +++ b/mql_test.go @@ -66,6 +66,16 @@ func TestParse(t *testing.T) { Args: []any{"%alice%"}, }, }, + { + name: "success-WithPgPlaceholder", + query: "name=bob or (name%alice or name=eve)", + model: testModel{}, + opts: []mql.Option{mql.WithPgPlaceholders()}, + want: &mql.WhereClause{ + Condition: "(name=$1 or (name like $2 or name=$3))", + Args: []any{"bob", "%alice%", "eve"}, + }, + }, { name: "err-leftExpr-without-op", query: "age (name=alice)", diff --git a/options.go b/options.go index 2d23c34..d0b54ea 100644 --- a/options.go +++ b/options.go @@ -13,6 +13,7 @@ type options struct { withValidateConvertFn ValidateConvertFunc withValidateConvertColumn string withIgnoredFields []string + withPgPlaceholder bool } // Option - how options are passed as args @@ -91,3 +92,15 @@ func WithIgnoredFields(fieldName ...string) Option { return nil } } + +// WithPgPlaceholders will use parameters placeholders that are compatible with +// the postgres pg driver which requires a placeholder like $1 instead of ?. +// See: +// - https://pkg.go.dev/github.com/jackc/pgx/v5 +// - https://pkg.go.dev/github.com/lib/pq +func WithPgPlaceholders() Option { + return func(o *options) error { + o.withPgPlaceholder = true + return nil + } +}