diff options
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.go | 148 |
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 } |