mirror of
https://github.com/1f349/lotus.git
synced 2024-12-23 00:24:17 +00:00
77 lines
1.4 KiB
Go
77 lines
1.4 KiB
Go
|
package map_provider
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
"unicode"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ErrMissingArgument = errors.New("missing argument")
|
||
|
ErrInvalidRawQuery = errors.New("invalid raw query")
|
||
|
)
|
||
|
|
||
|
type PreparedQuery struct {
|
||
|
raw string
|
||
|
params map[int]byte
|
||
|
}
|
||
|
|
||
|
func NewPreparedQuery(raw string) (*PreparedQuery, error) {
|
||
|
var s strings.Builder
|
||
|
origin := 0
|
||
|
params := make(map[int]byte)
|
||
|
for {
|
||
|
n := strings.IndexByte(raw[origin:], '%')
|
||
|
if n == -1 {
|
||
|
break
|
||
|
}
|
||
|
n += origin
|
||
|
if n+1 == len(raw) {
|
||
|
return nil, ErrInvalidRawQuery
|
||
|
}
|
||
|
s.WriteString(raw[origin:n])
|
||
|
if raw[n+1] == '%' {
|
||
|
s.WriteByte('%')
|
||
|
origin = n + 1
|
||
|
continue
|
||
|
}
|
||
|
params[s.Len()] = toLower(raw[n+1])
|
||
|
origin = n + 2
|
||
|
}
|
||
|
s.WriteString(raw[origin:])
|
||
|
return &PreparedQuery{
|
||
|
raw: s.String(),
|
||
|
params: params,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (p *PreparedQuery) Format(args map[byte]string) (string, error) {
|
||
|
var s strings.Builder
|
||
|
keys := make([]int, 0, len(p.params))
|
||
|
for k := range p.params {
|
||
|
keys = append(keys, k)
|
||
|
}
|
||
|
sort.Ints(keys)
|
||
|
origin := 0
|
||
|
for _, k := range keys {
|
||
|
r, ok := args[p.params[k]]
|
||
|
if !ok {
|
||
|
return "", ErrMissingArgument
|
||
|
}
|
||
|
|
||
|
// write up to and including the next parameter
|
||
|
s.WriteString(p.raw[origin:k])
|
||
|
s.WriteString(strings.ReplaceAll(r, "'", ""))
|
||
|
origin = k
|
||
|
}
|
||
|
|
||
|
// write the rest of the query
|
||
|
s.WriteString(p.raw[origin:])
|
||
|
return s.String(), nil
|
||
|
}
|
||
|
|
||
|
func toLower(a byte) byte {
|
||
|
return byte(unicode.ToLower(rune(a)))
|
||
|
}
|