Files
releases/vendor/github.com/huandu/go-sqlbuilder/modifiers.go
T
Stephan Renatus 4ab2ac0c61 Port Compile API extensions from EOPA (#7887)
* server: port compile API

Also adds e2e tests: These include coverage for ucast in the prisma
setting, and thus require some JS runtime.

* e2e: selectively skip e2e Compile API tests

...for macos runs, and for the go-compat suites.

* server: accept timer_rego_external_resolve_ns metrics with value 0

When running the tests in a loop for a while, I would see values of 0ns
for this metric. However, comparing with its non-zero values, which are
often 41 or 42ns, it seems like this is just not happening in this code
path. So if "almost nothing" actually goes below 1ns, it's OK.

* e2e: split dep-heavy e2e tests into their own go module
* Makefile: export DOCKER_RUNNING (make e2e read it)

---------

Co-authored-by: Philip Conrad <philip@chariot-chaser.net>
Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2025-09-22 12:11:06 +02:00

126 lines
2.6 KiB
Go

// Copyright 2018 Huan Du. All rights reserved.
// Licensed under the MIT license that can be found in the LICENSE file.
package sqlbuilder
import (
"reflect"
"strings"
)
// Escape replaces `$` with `$$` in ident.
func Escape(ident string) string {
return strings.Replace(ident, "$", "$$", -1)
}
// EscapeAll replaces `$` with `$$` in all strings of ident.
func EscapeAll(ident ...string) []string {
escaped := make([]string, 0, len(ident))
for _, i := range ident {
escaped = append(escaped, Escape(i))
}
return escaped
}
// Flatten recursively extracts values in slices and returns
// a flattened []interface{} with all values.
// If slices is not a slice, return `[]interface{}{slices}`.
func Flatten(slices interface{}) (flattened []interface{}) {
v := reflect.ValueOf(slices)
slices, flattened = flatten(v)
if slices != nil {
return []interface{}{slices}
}
return flattened
}
func flatten(v reflect.Value) (elem interface{}, flattened []interface{}) {
k := v.Kind()
for k == reflect.Interface {
v = v.Elem()
k = v.Kind()
}
if k != reflect.Slice && k != reflect.Array {
if !v.IsValid() || !v.CanInterface() {
return
}
elem = v.Interface()
return elem, nil
}
for i, l := 0, v.Len(); i < l; i++ {
e, f := flatten(v.Index(i))
if e == nil {
flattened = append(flattened, f...)
} else {
flattened = append(flattened, e)
}
}
return
}
type rawArgs struct {
expr string
}
// Raw marks the expr as a raw value which will not be added to args.
func Raw(expr string) interface{} {
return rawArgs{expr}
}
type listArgs struct {
args []interface{}
isTuple bool
}
// List marks arg as a list of data.
// If arg is `[]int{1, 2, 3}`, it will be compiled to `?, ?, ?` with args `[1 2 3]`.
func List(arg interface{}) interface{} {
return listArgs{
args: Flatten(arg),
}
}
// Tuple wraps values into a tuple and can be used as a single value.
func Tuple(values ...interface{}) interface{} {
return listArgs{
args: values,
isTuple: true,
}
}
// TupleNames joins names with tuple format.
// The names is not escaped. Use `EscapeAll` to escape them if necessary.
func TupleNames(names ...string) string {
buf := newStringBuilder()
buf.WriteRune('(')
buf.WriteStrings(names, ", ")
buf.WriteRune(')')
return buf.String()
}
type namedArgs struct {
name string
arg interface{}
}
// Named creates a named argument.
// Unlike `sql.Named`, this named argument works only with `Build` or `BuildNamed` for convenience
// and will be replaced to a `?` after `Compile`.
func Named(name string, arg interface{}) interface{} {
return namedArgs{
name: name,
arg: arg,
}
}