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