2020-04-10 08:27:43 +02:00
|
|
|
package core
|
2019-04-19 07:55:03 +02:00
|
|
|
|
|
|
|
import (
|
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
|
|
|
|
2020-05-27 01:41:28 +02:00
|
|
|
"github.com/dosco/super-graph/core/internal/psql"
|
2019-09-05 06:09:56 +02:00
|
|
|
"github.com/dosco/super-graph/jsn"
|
2019-04-19 07:55:03 +02:00
|
|
|
)
|
|
|
|
|
2020-05-01 08:20:13 +02:00
|
|
|
// argList function is used to create a list of arguments to pass
|
2020-05-27 01:41:28 +02:00
|
|
|
// to a prepared statement.
|
|
|
|
|
|
|
|
func (c *scontext) argList(md psql.Metadata) ([]interface{}, error) {
|
2020-06-05 03:55:52 +02:00
|
|
|
params := md.Params()
|
|
|
|
vars := make([]interface{}, len(params))
|
2019-09-05 06:09:56 +02:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-06-05 03:55:52 +02:00
|
|
|
for i, p := range params {
|
2020-05-27 01:41:28 +02:00
|
|
|
switch p.Name {
|
|
|
|
case "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-05-27 01:41:28 +02:00
|
|
|
return nil, argErr(p)
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
2020-05-27 01:41:28 +02:00
|
|
|
case "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-05-27 01:41:28 +02:00
|
|
|
return nil, argErr(p)
|
2019-07-29 07:13:33 +02:00
|
|
|
}
|
|
|
|
|
2020-05-27 01:41:28 +02:00
|
|
|
case "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-05-27 01:41:28 +02:00
|
|
|
return nil, argErr(p)
|
2020-02-19 05:52:44 +01:00
|
|
|
}
|
|
|
|
|
2020-05-27 01:41:28 +02:00
|
|
|
case "cursor":
|
2020-02-19 05:52:44 +01:00
|
|
|
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 {
|
2020-05-27 01:41:28 +02:00
|
|
|
return nil, argErr(p)
|
2019-11-05 05:44:42 +01:00
|
|
|
}
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
default:
|
2020-05-27 01:41:28 +02:00
|
|
|
if v, ok := fields[p.Name]; ok {
|
|
|
|
switch {
|
|
|
|
case p.IsArray && v[0] != '[':
|
|
|
|
return nil, fmt.Errorf("variable '%s' should be an array of type '%s'", p.Name, p.Type)
|
|
|
|
|
|
|
|
case p.Type == "json" && v[0] != '[' && v[0] != '{':
|
|
|
|
return nil, fmt.Errorf("variable '%s' should be an array or object", p.Name)
|
|
|
|
}
|
|
|
|
|
2019-12-25 07:24:30 +01:00
|
|
|
switch v[0] {
|
|
|
|
case '[', '{':
|
2020-05-27 01:41:28 +02:00
|
|
|
vars[i] = v
|
2020-05-24 23:43:54 +02:00
|
|
|
|
2019-12-25 07:24:30 +01:00
|
|
|
default:
|
|
|
|
var val interface{}
|
|
|
|
if err := json.Unmarshal(v, &val); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
vars[i] = val
|
|
|
|
}
|
|
|
|
|
2019-11-25 08:22:33 +01:00
|
|
|
} else {
|
2020-05-27 01:41:28 +02:00
|
|
|
return nil, argErr(p)
|
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
|
|
|
|
2020-05-27 01:41:28 +02:00
|
|
|
func argErr(p psql.Param) error {
|
|
|
|
return fmt.Errorf("required variable '%s' of type '%s' must be set", p.Name, p.Type)
|
2020-02-19 05:52:44 +01:00
|
|
|
}
|