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
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/array.go	Sun Apr 19 23:47:36 2015 -0400
     1.3 @@ -0,0 +1,48 @@
     1.4 +package pqarrays
     1.5 +
     1.6 +import (
     1.7 +	"database/sql/driver"
     1.8 +	"errors"
     1.9 +	"strconv"
    1.10 +	"strings"
    1.11 +)
    1.12 +
    1.13 +var (
    1.14 +	ErrUnexpectedValueType = errors.New("expected value to be a string or []byte")
    1.15 +)
    1.16 +
    1.17 +type StringArray []string
    1.18 +
    1.19 +func (s StringArray) Value() (driver.Value, error) {
    1.20 +	output := make([]string, 0, len(s))
    1.21 +	for _, item := range s {
    1.22 +		item = strconv.Quote(item)
    1.23 +		item = strings.Replace(item, "'", "\\'", -1)
    1.24 +		output = append(output, item)
    1.25 +	}
    1.26 +	return []byte(`{` + strings.Join(output, ",") + `}`), nil
    1.27 +}
    1.28 +
    1.29 +func (s *StringArray) Scan(value interface{}) error {
    1.30 +	*s = (*s)[:0]
    1.31 +	var input string
    1.32 +	if _, ok := value.(string); ok {
    1.33 +		input = value.(string)
    1.34 +	} else if _, ok := value.([]byte); ok {
    1.35 +		input = string(value.([]byte))
    1.36 +	} else {
    1.37 +		return ErrUnexpectedValueType
    1.38 +	}
    1.39 +	l := lex(input)
    1.40 +	parsed, err := parse(l)
    1.41 +	if err != nil {
    1.42 +		return err
    1.43 +	}
    1.44 +	for _, item := range parsed {
    1.45 +		if item == nil {
    1.46 +			continue
    1.47 +		}
    1.48 +		*s = append(*s, *item)
    1.49 +	}
    1.50 +	return nil
    1.51 +}