Skip to content

Commit

Permalink
fix: correctly handle bun.In([][]byte{...})
Browse files Browse the repository at this point in the history
  • Loading branch information
vmihailenco committed Mar 15, 2022
1 parent de14054 commit 800616e
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 55 deletions.
53 changes: 2 additions & 51 deletions bun.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package bun

import (
"context"
"fmt"
"reflect"

"github.com/uptrace/bun/internal"
"github.com/uptrace/bun/schema"
Expand Down Expand Up @@ -81,53 +79,6 @@ func SetLogger(logger internal.Logging) {
internal.Logger = logger
}

//------------------------------------------------------------------------------

type InValues struct {
slice reflect.Value
err error
}

var _ schema.QueryAppender = InValues{}

func In(slice interface{}) InValues {
v := reflect.ValueOf(slice)
if v.Kind() != reflect.Slice {
return InValues{
err: fmt.Errorf("bun: In(non-slice %T)", slice),
}
}
return InValues{
slice: v,
}
}

func (in InValues) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, err error) {
if in.err != nil {
return nil, in.err
}
return appendIn(fmter, b, in.slice), nil
}

func appendIn(fmter schema.Formatter, b []byte, slice reflect.Value) []byte {
sliceLen := slice.Len()
for i := 0; i < sliceLen; i++ {
if i > 0 {
b = append(b, ", "...)
}

elem := slice.Index(i)
if elem.Kind() == reflect.Interface {
elem = elem.Elem()
}

if elem.Kind() == reflect.Slice {
b = append(b, '(')
b = appendIn(fmter, b, elem)
b = append(b, ')')
} else {
b = fmter.AppendValue(b, elem)
}
}
return b
func In(slice interface{}) schema.QueryAppender {
return schema.In(slice)
}
4 changes: 2 additions & 2 deletions example/opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ go run .
OTEL_EXPORTER_JAEGER_ENDPOINT=http://localhost:14268/api/traces go run .
```

**Uptrace** exporter:
[Uptrace](https://github.com/uptrace/uptrace) exporter:

```shell
UPTRACE_DSN="https://<token>@uptrace.dev/<project_id>" go run .
Expand All @@ -25,4 +25,4 @@ UPTRACE_DSN="https://<token>@uptrace.dev/<project_id>" go run .
## Links

- [Find instrumentations](https://opentelemetry.uptrace.dev/instrumentations/?lang=go)
- [OpenTelemetry Tracing API](https://opentelemetry.uptrace.dev/guide/go-tracing.html)
- [OpenTelemetry Go Tracing API](https://opentelemetry.uptrace.dev/guide/go-tracing.html)
4 changes: 2 additions & 2 deletions example/opentelemetry/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"go.opentelemetry.io/otel/codes"
)

var tracer = otel.Tracer("bunexample")
var tracer = otel.Tracer("github.com/uptrace/bun/example/opentelemetry")

func main() {
ctx := context.Background()
Expand All @@ -32,7 +32,7 @@ func main() {
db.AddQueryHook(bunotel.NewQueryHook())
// db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))

if _, err := db.NewCreateTable().Model((*TestModel)(nil)).Exec(ctx); err != nil {
if err := db.ResetModel(ctx, (*TestModel)(nil)); err != nil {
panic(err)
}

Expand Down
7 changes: 7 additions & 0 deletions internal/dbtest/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,13 @@ func TestQuery(t *testing.T) {
tm := time.Unix(0, 0)
return db.NewInsert().Model(&Model{Time: &tm})
},
func(db *bun.DB) schema.QueryAppender {
values := [][]byte{
[]byte("foo"),
[]byte("bar"),
}
return db.NewSelect().Where("x IN (?)", bun.In(values))
},
}

timeRE := regexp.MustCompile(`'2\d{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?(\+\d{2}:\d{2})?'`)
Expand Down
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mariadb-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN (X'666f6f', X'626172'))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mssql2019-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN (0x666f6f, 0x626172))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql5-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN (X'666f6f', X'626172'))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql8-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN (X'666f6f', X'626172'))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pg-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN ('\x666f6f', '\x626172'))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pgx-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN ('\x666f6f', '\x626172'))
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-sqlite-111
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * WHERE (x IN (X'666f6f', X'626172'))
52 changes: 52 additions & 0 deletions schema/append.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package schema

import (
"fmt"
"reflect"
"strconv"
"time"
Expand Down Expand Up @@ -47,3 +48,54 @@ func Append(fmter Formatter, b []byte, v interface{}) []byte {
return appender(fmter, b, vv)
}
}

//------------------------------------------------------------------------------

func In(slice interface{}) QueryAppender {
v := reflect.ValueOf(slice)
if v.Kind() != reflect.Slice {
return &inValues{
err: fmt.Errorf("bun: In(non-slice %T)", slice),
}
}
return &inValues{
slice: v,
}
}

type inValues struct {
slice reflect.Value
err error
}

var _ QueryAppender = (*inValues)(nil)

func (in *inValues) AppendQuery(fmter Formatter, b []byte) (_ []byte, err error) {
if in.err != nil {
return nil, in.err
}
return appendIn(fmter, b, in.slice), nil
}

func appendIn(fmter Formatter, b []byte, slice reflect.Value) []byte {
sliceLen := slice.Len()
for i := 0; i < sliceLen; i++ {
if i > 0 {
b = append(b, ", "...)
}

elem := slice.Index(i)
if elem.Kind() == reflect.Interface {
elem = elem.Elem()
}

if elem.Kind() == reflect.Slice && elem.Type() != bytesType {
b = append(b, '(')
b = appendIn(fmter, b, elem)
b = append(b, ')')
} else {
b = fmter.AppendValue(b, elem)
}
}
return b
}

0 comments on commit 800616e

Please sign in to comment.