summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go')
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go158
1 files changed, 58 insertions, 100 deletions
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go
index 7a18b50b1..fec401786 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/hstore_parser.go
@@ -3,140 +3,98 @@ package pgdialect
import (
"bytes"
"fmt"
+ "io"
)
type hstoreParser struct {
- *streamParser
- err error
+ p pgparser
+
+ key string
+ value string
+ err error
}
func newHStoreParser(b []byte) *hstoreParser {
- p := &hstoreParser{
- streamParser: newStreamParser(b, 0),
- }
- if len(b) < 6 || b[0] != '"' {
- p.err = fmt.Errorf("bun: can't parse hstore: %q", b)
+ p := new(hstoreParser)
+ if len(b) != 0 && (len(b) < 6 || b[0] != '"') {
+ p.err = fmt.Errorf("pgdialect: can't parse hstore: %q", b)
+ return p
}
+ p.p.Reset(b)
return p
}
-func (p *hstoreParser) NextKey() (string, error) {
+func (p *hstoreParser) Next() bool {
if p.err != nil {
- return "", p.err
+ return false
}
+ p.err = p.readNext()
+ return p.err == nil
+}
- err := p.skipByte('"')
- if err != nil {
- return "", err
+func (p *hstoreParser) Err() error {
+ if p.err != io.EOF {
+ return p.err
}
+ return nil
+}
- key, err := p.readSubstring()
- if err != nil {
- return "", err
- }
+func (p *hstoreParser) Key() string {
+ return p.key
+}
- const separator = "=>"
+func (p *hstoreParser) Value() string {
+ return p.value
+}
- for i := range separator {
- err = p.skipByte(separator[i])
- if err != nil {
- return "", err
- }
+func (p *hstoreParser) readNext() error {
+ if !p.p.Valid() {
+ return io.EOF
}
- return string(key), nil
-}
+ if err := p.p.Skip('"'); err != nil {
+ return err
+ }
-func (p *hstoreParser) NextValue() (string, error) {
- if p.err != nil {
- return "", p.err
+ key, err := p.p.ReadUnescapedSubstring('"')
+ if err != nil {
+ return err
+ }
+ p.key = string(key)
+
+ if err := p.p.SkipPrefix([]byte("=>")); err != nil {
+ return err
}
- c, err := p.readByte()
+ ch, err := p.p.ReadByte()
if err != nil {
- return "", err
+ return err
}
- switch c {
+ switch ch {
case '"':
- value, err := p.readSubstring()
+ value, err := p.p.ReadUnescapedSubstring(ch)
if err != nil {
- return "", err
- }
-
- if p.peek() == ',' {
- p.skipNext()
- }
-
- if p.peek() == ' ' {
- p.skipNext()
+ return err
}
-
- return string(value), nil
+ p.skipComma()
+ p.value = string(value)
+ return nil
default:
- value := p.readSimple()
+ value := p.p.ReadLiteral(ch)
if bytes.Equal(value, []byte("NULL")) {
- value = nil
- }
-
- if p.peek() == ',' {
- p.skipNext()
+ p.value = ""
}
-
- return string(value), nil
- }
-}
-
-func (p *hstoreParser) 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
+ p.skipComma()
+ return nil
}
-
- b := p.b[p.i:len(p.b)]
- p.i = len(p.b)
- return b
}
-func (p *hstoreParser) readSubstring() ([]byte, error) {
- c, err := p.readByte()
- if err != nil {
- return nil, err
+func (p *hstoreParser) skipComma() {
+ if p.p.Peek() == ',' {
+ p.p.Advance()
}
-
- p.buf = p.buf[:0]
- for {
- if c == '"' {
- break
- }
-
- next, err := p.readByte()
- if err != nil {
- return nil, err
- }
-
- 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
- }
-
- p.buf = append(p.buf, c)
- c = next
+ if p.p.Peek() == ' ' {
+ p.p.Advance()
}
-
- return p.buf, nil
}