super-graph/serv/prepare.go

92 lines
1.5 KiB
Go
Raw Normal View History

2019-07-29 07:13:33 +02:00
package serv
import (
"bytes"
2019-09-05 06:09:56 +02:00
"encoding/json"
2019-07-29 07:13:33 +02:00
"fmt"
"io"
2019-09-05 06:09:56 +02:00
"github.com/dosco/super-graph/psql"
2019-07-29 07:13:33 +02:00
"github.com/dosco/super-graph/qcode"
"github.com/go-pg/pg"
"github.com/valyala/fasttemplate"
)
type preparedItem struct {
stmt *pg.Stmt
2019-09-05 06:09:56 +02:00
args [][]byte
2019-07-29 07:13:33 +02:00
skipped uint32
qc *qcode.QCode
}
var (
_preparedList map[string]*preparedItem
)
func initPreparedList() {
_preparedList = make(map[string]*preparedItem)
for k, v := range _allowList.list {
2019-09-05 06:09:56 +02:00
err := prepareStmt(k, v.gql, v.vars)
2019-07-29 07:13:33 +02:00
if err != nil {
panic(err)
}
}
}
2019-09-05 06:09:56 +02:00
func prepareStmt(key, gql string, varBytes json.RawMessage) error {
2019-07-29 07:13:33 +02:00
if len(gql) == 0 || len(key) == 0 {
return nil
}
2019-09-05 06:09:56 +02:00
qc, err := qcompile.Compile([]byte(gql))
2019-07-29 07:13:33 +02:00
if err != nil {
return err
}
2019-09-05 06:09:56 +02:00
var vars map[string]json.RawMessage
if len(varBytes) != 0 {
vars = make(map[string]json.RawMessage)
if err := json.Unmarshal(varBytes, &vars); err != nil {
return err
}
}
2019-07-29 07:13:33 +02:00
buf := &bytes.Buffer{}
2019-09-05 06:09:56 +02:00
skipped, err := pcompile.Compile(qc, buf, psql.Variables(vars))
2019-07-29 07:13:33 +02:00
if err != nil {
return err
}
2019-09-05 06:09:56 +02:00
t := fasttemplate.New(buf.String(), `{{`, `}}`)
am := make([][]byte, 0, 5)
2019-07-29 07:13:33 +02:00
i := 0
finalSQL := t.ExecuteFuncString(func(w io.Writer, tag string) (int, error) {
2019-09-05 06:09:56 +02:00
am = append(am, []byte(tag))
2019-07-29 07:13:33 +02:00
i++
return w.Write([]byte(fmt.Sprintf("$%d", i)))
})
if err != nil {
return err
}
pstmt, err := db.Prepare(finalSQL)
if err != nil {
return err
}
_preparedList[key] = &preparedItem{
stmt: pstmt,
args: am,
skipped: skipped,
qc: qc,
}
return nil
}