diff options
author | 2021-08-25 15:34:33 +0200 | |
---|---|---|
committer | 2021-08-25 15:34:33 +0200 | |
commit | 2dc9fc1626507bb54417fc4a1920b847cafb27a2 (patch) | |
tree | 4ddeac479b923db38090aac8bd9209f3646851c1 /vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go | |
parent | Manually approves followers (#146) (diff) | |
download | gotosocial-2dc9fc1626507bb54417fc4a1920b847cafb27a2.tar.xz |
Pg to bun (#148)
* start moving to bun
* changing more stuff
* more
* and yet more
* tests passing
* seems stable now
* more big changes
* small fix
* little fixes
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 | 146 |
1 files changed, 146 insertions, 0 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 new file mode 100644 index 000000000..1c927fca0 --- /dev/null +++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go @@ -0,0 +1,146 @@ +package pgdialect + +import ( + "bytes" + "fmt" + "io" +) + +type arrayParser struct { + b []byte + i int + + buf []byte + err error +} + +func newArrayParser(b []byte) *arrayParser { + p := &arrayParser{ + b: b, + i: 1, + } + if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' { + p.err = fmt.Errorf("bun: can't parse array: %q", b) + } + return p +} + +func (p *arrayParser) NextElem() ([]byte, error) { + if p.err != nil { + return nil, p.err + } + + c, err := p.readByte() + if err != nil { + return nil, err + } + + switch c { + case '}': + return nil, io.EOF + case '"': + b, err := p.readSubstring() + if err != nil { + return nil, err + } + + if p.peek() == ',' { + p.skipNext() + } + + return b, nil + default: + b := p.readSimple() + if bytes.Equal(b, []byte("NULL")) { + b = nil + } + + if p.peek() == ',' { + p.skipNext() + } + + 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 + } + + 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 + } + + return p.buf, nil +} + +func (p *arrayParser) valid() bool { + return p.i < len(p.b) +} + +func (p *arrayParser) readByte() (byte, error) { + if p.valid() { + c := p.b[p.i] + p.i++ + return c, nil + } + return 0, io.EOF +} + +func (p *arrayParser) unreadByte() { + p.i-- +} + +func (p *arrayParser) peek() byte { + if p.valid() { + return p.b[p.i] + } + return 0 +} + +func (p *arrayParser) skipNext() { + p.i++ +} |