pqarrays

Paddy 2015-04-19 Child:ce9c92fc81ab

0:bfe2a4af6bdf Go to Latest

pqarrays/array.go

First pass implementation. Use a lexer to generate tokens out of the Array type responses that PostgreSQL will send. Write a parser for string[] array types. Create a StringArray type that fulfills the driver.Valuer and sql.Scanner interfaces using the parser and lexer.

History
paddy@0 1 package pqarrays
paddy@0 2
paddy@0 3 import (
paddy@0 4 "database/sql/driver"
paddy@0 5 "errors"
paddy@0 6 "strconv"
paddy@0 7 "strings"
paddy@0 8 )
paddy@0 9
paddy@0 10 var (
paddy@0 11 ErrUnexpectedValueType = errors.New("expected value to be a string or []byte")
paddy@0 12 )
paddy@0 13
paddy@0 14 type StringArray []string
paddy@0 15
paddy@0 16 func (s StringArray) Value() (driver.Value, error) {
paddy@0 17 output := make([]string, 0, len(s))
paddy@0 18 for _, item := range s {
paddy@0 19 item = strconv.Quote(item)
paddy@0 20 item = strings.Replace(item, "'", "\\'", -1)
paddy@0 21 output = append(output, item)
paddy@0 22 }
paddy@0 23 return []byte(`{` + strings.Join(output, ",") + `}`), nil
paddy@0 24 }
paddy@0 25
paddy@0 26 func (s *StringArray) Scan(value interface{}) error {
paddy@0 27 *s = (*s)[:0]
paddy@0 28 var input string
paddy@0 29 if _, ok := value.(string); ok {
paddy@0 30 input = value.(string)
paddy@0 31 } else if _, ok := value.([]byte); ok {
paddy@0 32 input = string(value.([]byte))
paddy@0 33 } else {
paddy@0 34 return ErrUnexpectedValueType
paddy@0 35 }
paddy@0 36 l := lex(input)
paddy@0 37 parsed, err := parse(l)
paddy@0 38 if err != nil {
paddy@0 39 return err
paddy@0 40 }
paddy@0 41 for _, item := range parsed {
paddy@0 42 if item == nil {
paddy@0 43 continue
paddy@0 44 }
paddy@0 45 *s = append(*s, *item)
paddy@0 46 }
paddy@0 47 return nil
paddy@0 48 }