diff --git a/util/sqlutil/fetch.go b/util/sqlutil/fetch.go index 04196873ce056d70549a00bb5aa704e9931133bf..1d057f27621b505aa68d6d6b2922d22a68c21a7e 100644 --- a/util/sqlutil/fetch.go +++ b/util/sqlutil/fetch.go @@ -165,6 +165,9 @@ func fetchResult(itemT reflect.Type, rows *sqlx.Rows, columns []string) (reflect if _, ok := fi.Options["stringarray"]; ok { values[i] = &StringArray{} wrappedValues[f] = values[i] + } else if _, ok := fi.Options["int64array"]; ok { + values[i] = &Int64Array{} + wrappedValues[f] = values[i] } else if _, ok := fi.Options["jsonb"]; ok { values[i] = &JsonbType{} wrappedValues[f] = values[i] diff --git a/util/sqlutil/scanner.go b/util/sqlutil/scanner.go index a9c5f9cc7dab1bd1ba29aa4171b3e3c92ec13a5b..7d08bee6f05cef8d4128bb83b7b098f419267ae2 100644 --- a/util/sqlutil/scanner.go +++ b/util/sqlutil/scanner.go @@ -26,6 +26,7 @@ import ( "database/sql/driver" "encoding/json" "errors" + "strconv" "strings" "upper.io/db" @@ -128,3 +129,54 @@ func appendArrayQuotedString(b []byte, v string) []byte { } return append(b, '"') } + +//------ + +type Int64Array []int64 + +func (a *Int64Array) Scan(src interface{}) error { + if src == nil { + return nil + } + b, ok := src.([]byte) + if !ok { + return errors.New("Scan source was not []bytes") + } + + s := string(b)[1 : len(b)-1] + parts := strings.Split(s, ",") + results := make([]int64, 0) + for _, n := range parts { + i, err := strconv.ParseInt(n, 10, 64) + if err != nil { + return err + } + results = append(results, i) + } + *a = Int64Array(results) + return nil +} + +// Value implements the driver.Valuer interface. +func (a Int64Array) Value() (driver.Value, error) { + if a == nil { + return nil, nil + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, N bytes of values, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+2*n) + b[0] = '{' + + b = strconv.AppendInt(b, a[0], 10) + for i := 1; i < n; i++ { + b = append(b, ',') + b = strconv.AppendInt(b, a[i], 10) + } + + return append(b, '}'), nil + } + + return []byte{'{', '}'}, nil +} diff --git a/util/sqlutil/sqlutil.go b/util/sqlutil/sqlutil.go index 73f8873bccded61575be16edf622e5c704fb4699..ab3cbc6e76d4aceff0b7268b668dde087aa1c9d9 100644 --- a/util/sqlutil/sqlutil.go +++ b/util/sqlutil/sqlutil.go @@ -92,6 +92,9 @@ func (t *T) FieldValues(item interface{}) ([]string, []interface{}, error) { var value interface{} if _, ok := fi.Options["stringarray"]; ok { value = StringArray(fld.Interface().([]string)) + } else if _, ok := fi.Options["int64array"]; ok { + value = Int64Array(fld.Interface().([]int64)) + } else if _, ok := fi.Options["jsonb"]; ok { value = JsonbType{fld.Interface()} } else {