summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go')
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go148
1 files changed, 54 insertions, 94 deletions
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
index a8358337e..462f8d91d 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
@@ -2,132 +2,92 @@ package pgdialect
import (
"bytes"
- "encoding/hex"
"fmt"
"io"
)
type arrayParser struct {
- *streamParser
- err error
+ p pgparser
+
+ elem []byte
+ err error
}
func newArrayParser(b []byte) *arrayParser {
- p := &arrayParser{
- streamParser: newStreamParser(b, 1),
- }
+ p := new(arrayParser)
+
if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' {
- p.err = fmt.Errorf("bun: can't parse array: %q", b)
+ p.err = fmt.Errorf("pgdialect: can't parse array: %q", b)
+ return p
}
+
+ p.p.Reset(b[1 : len(b)-1])
return p
}
-func (p *arrayParser) NextElem() ([]byte, error) {
+func (p *arrayParser) Next() bool {
if p.err != nil {
- return nil, p.err
+ return false
}
+ p.err = p.readNext()
+ return p.err == nil
+}
+
+func (p *arrayParser) Err() error {
+ if p.err != io.EOF {
+ return p.err
+ }
+ return nil
+}
- c, err := p.readByte()
- if err != nil {
- return nil, err
+func (p *arrayParser) Elem() []byte {
+ return p.elem
+}
+
+func (p *arrayParser) readNext() error {
+ ch := p.p.Read()
+ if ch == 0 {
+ return io.EOF
}
- switch c {
+ switch ch {
case '}':
- return nil, io.EOF
+ return io.EOF
case '"':
- b, err := p.readSubstring()
+ b, err := p.p.ReadSubstring(ch)
if err != nil {
- return nil, err
- }
-
- if p.peek() == ',' {
- p.skipNext()
+ return err
}
- return b, nil
- default:
- b := p.readSimple()
- if bytes.Equal(b, []byte("NULL")) {
- b = nil
+ if p.p.Peek() == ',' {
+ p.p.Advance()
}
- if p.peek() == ',' {
- p.skipNext()
+ p.elem = b
+ return nil
+ case '[', '(':
+ rng, err := p.p.ReadRange(ch)
+ if err != nil {
+ return err
}
- return b, nil
- }
-}
-
-func (p *arrayParser) readSimple() []byte {
- p.unreadByte()
-
- if i := bytes.IndexByte(p.b[p.i:], ','); i >= 0 {
- b := p.b[p.i : p.i+i]
- p.i += i
- return b
- }
-
- b := p.b[p.i : len(p.b)-1]
- p.i = len(p.b) - 1
- return b
-}
-
-func (p *arrayParser) readSubstring() ([]byte, error) {
- c, err := p.readByte()
- if err != nil {
- return nil, err
- }
-
- p.buf = p.buf[:0]
- for {
- if c == '"' {
- break
+ if p.p.Peek() == ',' {
+ p.p.Advance()
}
- next, err := p.readByte()
- if err != nil {
- return nil, err
+ p.elem = rng
+ return nil
+ default:
+ lit := p.p.ReadLiteral(ch)
+ if bytes.Equal(lit, []byte("NULL")) {
+ lit = nil
}
- if c == '\\' {
- switch next {
- case '\\', '"':
- p.buf = append(p.buf, next)
-
- c, err = p.readByte()
- if err != nil {
- return nil, err
- }
- default:
- p.buf = append(p.buf, '\\')
- c = next
- }
- continue
+ if p.p.Peek() == ',' {
+ p.p.Advance()
}
- if c == '\'' && next == '\'' {
- p.buf = append(p.buf, next)
- c, err = p.readByte()
- if err != nil {
- return nil, err
- }
- continue
- }
-
- p.buf = append(p.buf, c)
- c = next
- }
- if bytes.HasPrefix(p.buf, []byte("\\x")) && len(p.buf)%2 == 0 {
- data := p.buf[2:]
- buf := make([]byte, hex.DecodedLen(len(data)))
- n, err := hex.Decode(buf, data)
- if err != nil {
- return nil, err
- }
- return buf[:n], nil
+ p.elem = lit
+ return nil
}
-
- return p.buf, nil
}