2020-04-10 08:27:43 +02:00
|
|
|
package core
|
2019-04-19 07:55:03 +02:00
|
|
|
|
|
|
|
import (
|
2019-09-05 06:09:56 +02:00
|
|
|
"bytes"
|
2019-12-25 07:24:30 +01:00
|
|
|
"encoding/json"
|
2019-09-05 06:09:56 +02:00
|
|
|
"fmt"
|
2019-04-19 07:55:03 +02:00
|
|
|
"io"
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
"github.com/dosco/super-graph/jsn"
|
2019-04-19 07:55:03 +02:00
|
|
|
)
|
|
|
|
|
2020-04-10 08:27:43 +02:00
|
|
|
func (c *scontext) argMap() func(w io.Writer, tag string) (int, error) {
|
2019-09-05 06:09:56 +02:00
|
|
|
return func(w io.Writer, tag string) (int, error) {
|
|
|
|
switch tag {
|
2019-10-24 08:07:42 +02:00
|
|
|
case "user_id_provider":
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserIDProviderKey); v != nil {
|
2019-11-21 08:14:12 +01:00
|
|
|
return io.WriteString(w, v.(string))
|
2019-10-24 08:07:42 +02:00
|
|
|
}
|
2020-02-19 05:52:44 +01:00
|
|
|
return 0, argErr("user_id_provider")
|
2019-10-24 08:07:42 +02:00
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
case "user_id":
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserIDKey); v != nil {
|
2019-11-21 08:14:12 +01:00
|
|
|
return io.WriteString(w, v.(string))
|
2019-09-05 06:09:56 +02:00
|
|
|
}
|
2020-02-19 05:52:44 +01:00
|
|
|
return 0, argErr("user_id")
|
2019-10-24 08:07:42 +02:00
|
|
|
|
|
|
|
case "user_role":
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserRoleKey); v != nil {
|
2019-11-21 08:14:12 +01:00
|
|
|
return io.WriteString(w, v.(string))
|
2019-09-05 06:09:56 +02:00
|
|
|
}
|
2020-02-19 05:52:44 +01:00
|
|
|
return 0, argErr("user_role")
|
2019-04-19 07:55:03 +02:00
|
|
|
}
|
|
|
|
|
2020-04-10 08:27:43 +02:00
|
|
|
fields := jsn.Get(c.vars, [][]byte{[]byte(tag)})
|
2020-01-15 05:16:55 +01:00
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
if len(fields) == 0 {
|
2020-02-19 05:52:44 +01:00
|
|
|
return 0, argErr(tag)
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
}
|
2019-12-09 07:48:18 +01:00
|
|
|
v := fields[0].Value
|
2020-02-23 21:29:50 +01:00
|
|
|
|
|
|
|
// Open and close quotes
|
2019-12-09 07:48:18 +01:00
|
|
|
if len(v) >= 2 && v[0] == '"' && v[len(v)-1] == '"' {
|
|
|
|
fields[0].Value = v[1 : len(v)-1]
|
|
|
|
}
|
2019-04-19 07:55:03 +02:00
|
|
|
|
2020-02-19 05:52:44 +01:00
|
|
|
if tag == "cursor" {
|
2020-02-23 21:29:50 +01:00
|
|
|
if bytes.EqualFold(v, []byte("null")) {
|
|
|
|
return io.WriteString(w, ``)
|
|
|
|
}
|
2020-04-10 08:27:43 +02:00
|
|
|
v1, err := c.sg.decrypt(string(fields[0].Value))
|
2020-02-19 05:52:44 +01:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return w.Write(v1)
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:02:12 +01:00
|
|
|
return w.Write(escQuote(fields[0].Value))
|
2019-04-19 07:55:03 +02:00
|
|
|
}
|
|
|
|
}
|
2019-07-29 07:13:33 +02:00
|
|
|
|
2020-04-10 08:27:43 +02:00
|
|
|
func (c *scontext) argList(args [][]byte) ([]interface{}, error) {
|
2019-09-05 06:09:56 +02:00
|
|
|
vars := make([]interface{}, len(args))
|
|
|
|
|
2019-12-25 07:24:30 +01:00
|
|
|
var fields map[string]json.RawMessage
|
2019-09-05 06:09:56 +02:00
|
|
|
var err error
|
2019-07-29 07:13:33 +02:00
|
|
|
|
2020-04-10 08:27:43 +02:00
|
|
|
if len(c.vars) != 0 {
|
|
|
|
fields, _, err = jsn.Tree(c.vars)
|
2019-09-05 06:09:56 +02:00
|
|
|
|
|
|
|
if err != nil {
|
2019-11-25 08:22:33 +01:00
|
|
|
return nil, err
|
2019-09-05 06:09:56 +02:00
|
|
|
}
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for i := range args {
|
2019-09-05 06:09:56 +02:00
|
|
|
av := args[i]
|
|
|
|
switch {
|
|
|
|
case bytes.Equal(av, []byte("user_id")):
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserIDKey); v != nil {
|
2019-09-05 06:09:56 +02:00
|
|
|
vars[i] = v.(string)
|
2019-11-25 08:22:33 +01:00
|
|
|
} else {
|
2020-02-19 05:52:44 +01:00
|
|
|
return nil, argErr("user_id")
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
case bytes.Equal(av, []byte("user_id_provider")):
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserIDProviderKey); v != nil {
|
2019-09-05 06:09:56 +02:00
|
|
|
vars[i] = v.(string)
|
2019-11-25 08:22:33 +01:00
|
|
|
} else {
|
2020-02-19 05:52:44 +01:00
|
|
|
return nil, argErr("user_id_provider")
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
2019-11-05 05:44:42 +01:00
|
|
|
case bytes.Equal(av, []byte("user_role")):
|
2020-04-10 08:27:43 +02:00
|
|
|
if v := c.Value(UserRoleKey); v != nil {
|
2019-11-05 05:44:42 +01:00
|
|
|
vars[i] = v.(string)
|
2019-11-25 08:22:33 +01:00
|
|
|
} else {
|
2020-02-19 05:52:44 +01:00
|
|
|
return nil, argErr("user_role")
|
|
|
|
}
|
|
|
|
|
|
|
|
case bytes.Equal(av, []byte("cursor")):
|
|
|
|
if v, ok := fields["cursor"]; ok && v[0] == '"' {
|
2020-04-10 08:27:43 +02:00
|
|
|
v1, err := c.sg.decrypt(string(v[1 : len(v)-1]))
|
2020-02-19 05:52:44 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
vars[i] = v1
|
|
|
|
} else {
|
|
|
|
return nil, argErr("cursor")
|
2019-11-05 05:44:42 +01:00
|
|
|
}
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
default:
|
|
|
|
if v, ok := fields[string(av)]; ok {
|
2019-12-25 07:24:30 +01:00
|
|
|
switch v[0] {
|
|
|
|
case '[', '{':
|
2020-01-14 07:02:12 +01:00
|
|
|
vars[i] = escQuote(v)
|
2019-12-25 07:24:30 +01:00
|
|
|
default:
|
|
|
|
var val interface{}
|
|
|
|
if err := json.Unmarshal(v, &val); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-02-19 05:52:44 +01:00
|
|
|
|
2019-12-25 07:24:30 +01:00
|
|
|
vars[i] = val
|
|
|
|
}
|
|
|
|
|
2019-11-25 08:22:33 +01:00
|
|
|
} else {
|
2020-02-19 05:52:44 +01:00
|
|
|
return nil, argErr(string(av))
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-25 08:22:33 +01:00
|
|
|
return vars, nil
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
2020-01-14 07:02:12 +01:00
|
|
|
|
|
|
|
func escQuote(b []byte) []byte {
|
|
|
|
f := false
|
|
|
|
for i := range b {
|
|
|
|
if b[i] == '\'' {
|
|
|
|
f = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !f {
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
s := 0
|
|
|
|
for i := range b {
|
|
|
|
if b[i] == '\'' {
|
|
|
|
buf.Write(b[s:i])
|
|
|
|
buf.WriteString(`''`)
|
|
|
|
s = i + 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
l := len(b)
|
|
|
|
if s < (l - 1) {
|
|
|
|
buf.Write(b[s:l])
|
|
|
|
}
|
|
|
|
return buf.Bytes()
|
|
|
|
}
|
2020-02-19 05:52:44 +01:00
|
|
|
|
|
|
|
func argErr(name string) error {
|
|
|
|
return fmt.Errorf("query requires variable '%s' to be set", name)
|
|
|
|
}
|