-
Notifications
You must be signed in to change notification settings - Fork 6
/
options.go
102 lines (89 loc) · 2.93 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package mql
import (
"fmt"
)
type options struct {
withSkipWhitespace bool
withColumnMap map[string]string
withValidateConvertFns map[string]ValidateConvertFunc
withIgnoredFields []string
withPgPlaceholder bool
}
// Option - how options are passed as args
type Option func(*options) error
func getDefaultOptions() options {
return options{
withColumnMap: make(map[string]string),
withValidateConvertFns: make(map[string]ValidateConvertFunc),
}
}
func getOpts(opt ...Option) (options, error) {
opts := getDefaultOptions()
for _, o := range opt {
if err := o(&opts); err != nil {
return opts, err
}
}
return opts, nil
}
// withSkipWhitespace provides an option to request that whitespace be skipped
func withSkipWhitespace() Option {
return func(o *options) error {
o.withSkipWhitespace = true
return nil
}
}
// WithColumnMap provides an optional map of columns from a column in the user
// provided query to a column in the database model
func WithColumnMap(m map[string]string) Option {
return func(o *options) error {
if !isNil(m) {
o.withColumnMap = m
}
return nil
}
}
// ValidateConvertFunc validates the value and then converts the columnName,
// comparisonOp and value to a WhereClause
type ValidateConvertFunc func(columnName string, comparisonOp ComparisonOp, value *string) (*WhereClause, error)
// WithConverter provides an optional ConvertFunc for a column identifier in the
// query. This allows you to provide whatever custom validation+conversion you
// need on a per column basis. See: DefaultValidateConvert(...) for inspiration.
func WithConverter(fieldName string, fn ValidateConvertFunc) Option {
const op = "mql.WithSqlConverter"
return func(o *options) error {
switch {
case fieldName != "" && !isNil(fn):
if _, exists := o.withValidateConvertFns[fieldName]; exists {
return fmt.Errorf("%s: duplicated convert: %w", op, ErrInvalidParameter)
}
o.withValidateConvertFns[fieldName] = fn
case fieldName == "" && !isNil(fn):
return fmt.Errorf("%s: missing field name: %w", op, ErrInvalidParameter)
case fieldName != "" && isNil(fn):
return fmt.Errorf("%s: missing ConvertToSqlFunc: %w", op, ErrInvalidParameter)
}
return nil
}
}
// WithIgnoredFields provides an optional list of fields to ignore in the model
// (your Go struct) when parsing. Note: Field names are case sensitive.
func WithIgnoredFields(fieldName ...string) Option {
return func(o *options) error {
o.withIgnoredFields = fieldName
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
}
}