array.go (1304B)
1 package pgdialect 2 3 import ( 4 "database/sql" 5 "fmt" 6 "reflect" 7 8 "github.com/uptrace/bun/schema" 9 ) 10 11 type ArrayValue struct { 12 v reflect.Value 13 14 append schema.AppenderFunc 15 scan schema.ScannerFunc 16 } 17 18 // Array accepts a slice and returns a wrapper for working with PostgreSQL 19 // array data type. 20 // 21 // For struct fields you can use array tag: 22 // 23 // Emails []string `bun:",array"` 24 func Array(vi interface{}) *ArrayValue { 25 v := reflect.ValueOf(vi) 26 if !v.IsValid() { 27 panic(fmt.Errorf("bun: Array(nil)")) 28 } 29 30 return &ArrayValue{ 31 v: v, 32 33 append: pgDialect.arrayAppender(v.Type()), 34 scan: arrayScanner(v.Type()), 35 } 36 } 37 38 var ( 39 _ schema.QueryAppender = (*ArrayValue)(nil) 40 _ sql.Scanner = (*ArrayValue)(nil) 41 ) 42 43 func (a *ArrayValue) AppendQuery(fmter schema.Formatter, b []byte) ([]byte, error) { 44 if a.append == nil { 45 panic(fmt.Errorf("bun: Array(unsupported %s)", a.v.Type())) 46 } 47 return a.append(fmter, b, a.v), nil 48 } 49 50 func (a *ArrayValue) Scan(src interface{}) error { 51 if a.scan == nil { 52 return fmt.Errorf("bun: Array(unsupported %s)", a.v.Type()) 53 } 54 if a.v.Kind() != reflect.Ptr { 55 return fmt.Errorf("bun: Array(non-pointer %s)", a.v.Type()) 56 } 57 return a.scan(a.v, src) 58 } 59 60 func (a *ArrayValue) Value() interface{} { 61 if a.v.IsValid() { 62 return a.v.Interface() 63 } 64 return nil 65 }