2021-08-25 13:34:33 +00:00
|
|
|
package pgdialect
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
|
|
|
type arrayParser struct {
|
2024-11-08 13:51:23 +00:00
|
|
|
p pgparser
|
|
|
|
|
|
|
|
elem []byte
|
|
|
|
err error
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func newArrayParser(b []byte) *arrayParser {
|
2024-11-08 13:51:23 +00:00
|
|
|
p := new(arrayParser)
|
|
|
|
|
2021-08-25 13:34:33 +00:00
|
|
|
if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' {
|
2024-11-08 13:51:23 +00:00
|
|
|
p.err = fmt.Errorf("pgdialect: can't parse array: %q", b)
|
|
|
|
return p
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
2024-11-08 13:51:23 +00:00
|
|
|
|
|
|
|
p.p.Reset(b[1 : len(b)-1])
|
2021-08-25 13:34:33 +00:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
func (p *arrayParser) Next() bool {
|
2021-08-25 13:34:33 +00:00
|
|
|
if p.err != nil {
|
2024-11-08 13:51:23 +00:00
|
|
|
return false
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
2024-11-08 13:51:23 +00:00
|
|
|
p.err = p.readNext()
|
|
|
|
return p.err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *arrayParser) Err() error {
|
|
|
|
if p.err != io.EOF {
|
|
|
|
return p.err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2021-08-25 13:34:33 +00:00
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
func (p *arrayParser) Elem() []byte {
|
|
|
|
return p.elem
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *arrayParser) readNext() error {
|
|
|
|
ch := p.p.Read()
|
|
|
|
if ch == 0 {
|
|
|
|
return io.EOF
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
switch ch {
|
2021-08-25 13:34:33 +00:00
|
|
|
case '}':
|
2024-11-08 13:51:23 +00:00
|
|
|
return io.EOF
|
2021-08-25 13:34:33 +00:00
|
|
|
case '"':
|
2024-11-08 13:51:23 +00:00
|
|
|
b, err := p.p.ReadSubstring(ch)
|
2021-08-25 13:34:33 +00:00
|
|
|
if err != nil {
|
2024-11-08 13:51:23 +00:00
|
|
|
return err
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
if p.p.Peek() == ',' {
|
|
|
|
p.p.Advance()
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
p.elem = b
|
|
|
|
return nil
|
|
|
|
case '[', '(':
|
|
|
|
rng, err := p.p.ReadRange(ch)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
if p.p.Peek() == ',' {
|
|
|
|
p.p.Advance()
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
p.elem = rng
|
|
|
|
return nil
|
|
|
|
default:
|
|
|
|
lit := p.p.ReadLiteral(ch)
|
|
|
|
if bytes.Equal(lit, []byte("NULL")) {
|
|
|
|
lit = nil
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
if p.p.Peek() == ',' {
|
|
|
|
p.p.Advance()
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|
|
|
|
|
2024-11-08 13:51:23 +00:00
|
|
|
p.elem = lit
|
|
|
|
return nil
|
2021-10-24 11:14:37 +00:00
|
|
|
}
|
2021-08-25 13:34:33 +00:00
|
|
|
}
|