pqarrays

Paddy 2016-02-25 Parent:bfe2a4af6bdf

1:ce9c92fc81ab Go to Latest

pqarrays/array.go

Fix bug parsing empty arrays, make golint and go vet happy. Add comments to make golint happy. Also, because comments are a good thing to have. Turn += 1 and -= 1 into ++ and --, respectively, so golint will be happy. Fix an improperly formated errorf, where a rune was being treated as a string. Thanks, go vet! Fix whitespace parsing, returning the parse functions again instead of just skipping the one character. Now if we have more than one whitespace character in a row, they'll all be skipped. Add a parseStringOrNullOrEnd parse function that will be called after the tokenArrayStart character, to fix a bug where empty arrays were expecting a string or null and getting the array end character. This is only valid after tokenArrayStart, however; in other places where parseSeparatorOrDelim is used, it wouldn't be appropriate. Add a parser test for an empty array.

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@1 11 // ErrUnexpectedValueType is returned when the passed value is not a string or []byte.
paddy@0 12 ErrUnexpectedValueType = errors.New("expected value to be a string or []byte")
paddy@0 13 )
paddy@0 14
paddy@1 15 // StringArray represents a Postgres array as a []string.
paddy@0 16 type StringArray []string
paddy@0 17
paddy@1 18 // Value implements the Valuer interface for StringArray, allowing it to be transparently
paddy@1 19 // stored in Postgres databases using the database/sql package.
paddy@0 20 func (s StringArray) Value() (driver.Value, error) {
paddy@0 21 output := make([]string, 0, len(s))
paddy@0 22 for _, item := range s {
paddy@0 23 item = strconv.Quote(item)
paddy@0 24 item = strings.Replace(item, "'", "\\'", -1)
paddy@0 25 output = append(output, item)
paddy@0 26 }
paddy@0 27 return []byte(`{` + strings.Join(output, ",") + `}`), nil
paddy@0 28 }
paddy@0 29
paddy@1 30 // Scan implements the Scanner interface for StringArray, allowing it to be transparently
paddy@1 31 // retrieved from Postgres databases using the database/sql package. It expects `value` to
paddy@1 32 // be a string or []byte, and throws ErrUnexpectedValueType when any other type is encountered.
paddy@0 33 func (s *StringArray) Scan(value interface{}) error {
paddy@0 34 *s = (*s)[:0]
paddy@0 35 var input string
paddy@0 36 if _, ok := value.(string); ok {
paddy@0 37 input = value.(string)
paddy@0 38 } else if _, ok := value.([]byte); ok {
paddy@0 39 input = string(value.([]byte))
paddy@0 40 } else {
paddy@0 41 return ErrUnexpectedValueType
paddy@0 42 }
paddy@0 43 l := lex(input)
paddy@0 44 parsed, err := parse(l)
paddy@0 45 if err != nil {
paddy@0 46 return err
paddy@0 47 }
paddy@0 48 for _, item := range parsed {
paddy@0 49 if item == nil {
paddy@0 50 continue
paddy@0 51 }
paddy@0 52 *s = append(*s, *item)
paddy@0 53 }
paddy@0 54 return nil
paddy@0 55 }