Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,25 @@ This can be useful for changing sort direction or embedding table and column nam

_Note: Since this is a raw value, special attention should be paid to ensure user-input is checked and sanitized._

### Folded

The `Folded` type and corresponding `ToFolded` generic function will prevent spreading of `[]string`, `[]int`, or `[]any`. For example, `bqb.New("?", []string{"a","b"})` will become `("?,?", "a", "b")` by default.

```go
strns := []string{"a", "b"}
q := bqb.New("Folded: ? - Default: ?", bqb.ToFolded(strns), strns)
// sql = Folded: ? - Default: ?,?
// params = { []string{"a", "b"}, "a", "b" }
```

## Query IN

Arguments of type `[]string`,`[]*string`, `[]int`,`[]*int`, or `[]interface{}` are automatically expanded.
Arguments of type `[]string`,`[]*string`, `[]int`,`[]*int`, and `[]any` / `[]interface{}` are automatically expanded.

```golang
q := bqb.New(
"strs:(?) *strs:(?) ints:(?) *ints:(?) intfs:(?)",
[]string{"a", "b"}, []*string{}, []int{1, 2}, []*int{}, []interface{}{3, true},
[]string{"a", "b"}, []*string{}, []int{1, 2}, []*int{}, []any{3, true},
)
sql, params, _ := q.ToSql()
```
Expand Down Expand Up @@ -197,7 +208,7 @@ SELECT id,age,email
### Advanced Example

The `Optional(string)` function returns a query that resolves to an empty string if no query parts have
been added via methods on the query instance, and joins with a space to the next query part.
been added via methods on the query instance, and joins with a space to the next query part.
For example `q := Optional("SELECT")` will resolve to an empty string unless parts have been added by one of the methods,
e.g `q.Space("* FROM my_table")` would make `q.ToSql()` resolve to `SELECT * FROM my_table`.

Expand Down
56 changes: 30 additions & 26 deletions coverage.out
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ github.com/nullism/bqb/query.go:176.2,176.28 1 1
github.com/nullism/bqb/query.go:176.28,180.23 3 1
github.com/nullism/bqb/query.go:180.23,182.4 1 1
github.com/nullism/bqb/query.go:185.2,185.44 1 1
github.com/nullism/bqb/types.go:43.40,45.26 2 1
github.com/nullism/bqb/types.go:45.26,47.3 1 1
github.com/nullism/bqb/types.go:48.2,48.17 1 1
github.com/nullism/bqb/utils.go:11.80,18.17 2 1
github.com/nullism/bqb/utils.go:19.11,20.32 1 1
github.com/nullism/bqb/utils.go:20.32,22.18 2 1
Expand Down Expand Up @@ -97,29 +100,30 @@ github.com/nullism/bqb/utils.go:135.27,138.17 3 1
github.com/nullism/bqb/utils.go:138.17,140.4 1 1
github.com/nullism/bqb/utils.go:140.9,142.4 1 1
github.com/nullism/bqb/utils.go:144.16,145.50 1 1
github.com/nullism/bqb/utils.go:147.10,149.31 2 1
github.com/nullism/bqb/utils.go:152.2,152.28 1 1
github.com/nullism/bqb/utils.go:155.64,157.20 2 1
github.com/nullism/bqb/utils.go:157.20,159.3 1 1
github.com/nullism/bqb/utils.go:161.2,162.28 2 1
github.com/nullism/bqb/utils.go:162.28,164.3 1 1
github.com/nullism/bqb/utils.go:165.2,165.12 1 1
github.com/nullism/bqb/utils.go:168.51,176.27 6 1
github.com/nullism/bqb/utils.go:176.27,178.23 2 1
github.com/nullism/bqb/utils.go:178.23,180.4 1 1
github.com/nullism/bqb/utils.go:181.3,182.51 2 1
github.com/nullism/bqb/utils.go:185.2,185.70 1 1
github.com/nullism/bqb/utils.go:185.70,187.3 1 1
github.com/nullism/bqb/utils.go:189.2,195.3 2 1
github.com/nullism/bqb/utils.go:198.44,199.27 1 1
github.com/nullism/bqb/utils.go:200.12,201.35 1 1
github.com/nullism/bqb/utils.go:203.33,204.35 1 1
github.com/nullism/bqb/utils.go:205.12,206.15 1 1
github.com/nullism/bqb/utils.go:206.15,208.4 1 1
github.com/nullism/bqb/utils.go:209.3,209.36 1 1
github.com/nullism/bqb/utils.go:210.14,211.37 1 1
github.com/nullism/bqb/utils.go:212.15,213.15 1 1
github.com/nullism/bqb/utils.go:213.15,215.4 1 1
github.com/nullism/bqb/utils.go:216.3,216.38 1 1
github.com/nullism/bqb/utils.go:217.11,218.21 1 1
github.com/nullism/bqb/utils.go:219.10,220.65 1 1
github.com/nullism/bqb/utils.go:147.23,149.31 2 1
github.com/nullism/bqb/utils.go:151.10,153.31 2 1
github.com/nullism/bqb/utils.go:156.2,156.28 1 1
github.com/nullism/bqb/utils.go:159.64,161.20 2 1
github.com/nullism/bqb/utils.go:161.20,163.3 1 1
github.com/nullism/bqb/utils.go:165.2,166.28 2 1
github.com/nullism/bqb/utils.go:166.28,168.3 1 1
github.com/nullism/bqb/utils.go:169.2,169.12 1 1
github.com/nullism/bqb/utils.go:172.51,180.27 6 1
github.com/nullism/bqb/utils.go:180.27,182.23 2 1
github.com/nullism/bqb/utils.go:182.23,184.4 1 1
github.com/nullism/bqb/utils.go:185.3,186.51 2 1
github.com/nullism/bqb/utils.go:189.2,189.70 1 1
github.com/nullism/bqb/utils.go:189.70,191.3 1 1
github.com/nullism/bqb/utils.go:193.2,199.3 2 1
github.com/nullism/bqb/utils.go:202.44,203.27 1 1
github.com/nullism/bqb/utils.go:204.12,205.35 1 1
github.com/nullism/bqb/utils.go:207.33,208.35 1 1
github.com/nullism/bqb/utils.go:209.12,210.15 1 1
github.com/nullism/bqb/utils.go:210.15,212.4 1 1
github.com/nullism/bqb/utils.go:213.3,213.36 1 1
github.com/nullism/bqb/utils.go:214.14,215.37 1 1
github.com/nullism/bqb/utils.go:216.15,217.15 1 1
github.com/nullism/bqb/utils.go:217.15,219.4 1 1
github.com/nullism/bqb/utils.go:220.3,220.38 1 1
github.com/nullism/bqb/utils.go:221.11,222.21 1 1
github.com/nullism/bqb/utils.go:223.10,224.65 1 1
33 changes: 29 additions & 4 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,43 @@ import (
"time"
)

func TestA(t *testing.T) {
func TestFolded(t *testing.T) {
valArr := ToFolded([]string{"a", "b", "c"})
wantValArr := Folded{"a", "b", "c"}

if valArr[0] != wantValArr[0] {
t.Errorf("got: %v, want: %v", valArr[0], wantValArr[0])
}

jsArr := JsonList{"a", "b", "c"}
fpArr := &Folded{"a", "b", "c"}

q := New("(?) (?) (?) (?)", valArr, jsArr, []string{"a", "b", "c"}, fpArr)
sql, params, err := q.ToSql()
if err != nil {
t.Errorf("got error: %v", err)
}

if len(params) != 6 {
t.Errorf("invalid params")
}

want := "(?) (?) (?,?,?) (?)"
if sql != want {
t.Errorf("got: %q, want: %q", sql, want)
}
}

func TestArrays(t *testing.T) {
q := New("(?) (?) (?) (?) (?)", []string{"a", "b"}, []string{}, []*string{}, []int{1, 2}, []*int{})
// float64 does not expand automatically
q := New("(?) (?) (?) (?) (?) (?) (?)", []string{"a", "b"}, []string{}, []*string{}, []int{1, 2}, []*int{}, []any{1.2, 1.3, 1.4}, []float64{1.1, 1.2})
sql, params, _ := q.ToSql()

if len(params) != 6 {
if len(params) != 10 {
t.Errorf("invalid params")
}

want := "(?,?) () (?) (?,?) (?)"
want := "(?,?) () (?) (?,?) (?) (?,?,?) (?)"
if sql != want {
t.Errorf("got: %q, want: %q", sql, want)
}
Expand Down
17 changes: 15 additions & 2 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@ type Embedder interface {

// JsonMap is a custom type which tells bqb to convert the parameter to
// a JSON object without requiring reflection.
type JsonMap map[string]interface{}
type JsonMap map[string]any

// JsonList is a type that tells bqb to convert the parameter to a JSON
// list without requiring reflection.
type JsonList []interface{}
type JsonList []any

// Folded is a type that tells bqb to NOT spread the list into individual
// parameters.
type Folded []any

// ToFolded converts a slice to a ValueArray.
func ToFolded[T any](slice []T) Folded {
valueArr := make(Folded, len(slice))
for i, v := range slice {
valueArr[i] = v
}
return valueArr
}
4 changes: 4 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func convertArg(text string, arg any) (string, []any, []error) {
case Embedded:
text = strings.Replace(text, "?", string(v), 1)

case Folded, *Folded:
text = strings.Replace(text, "?", paramPh, 1)
newArgs = append(newArgs, v)

default:
text = strings.Replace(text, "?", paramPh, 1)
newArgs = append(newArgs, v)
Expand Down