fix: make array variables work again
This commit is contained in:
44
core/args.go
44
core/args.go
@ -41,6 +41,10 @@ func (c *scontext) argMap() func(w io.Writer, tag string) (int, error) {
|
||||
}
|
||||
v := fields[0].Value
|
||||
|
||||
if isJsonScalarArray(v) {
|
||||
return w.Write(jsonListToValues(v))
|
||||
}
|
||||
|
||||
// Open and close quotes
|
||||
if len(v) >= 2 && v[0] == '"' && v[len(v)-1] == '"' {
|
||||
fields[0].Value = v[1 : len(v)-1]
|
||||
@ -118,13 +122,17 @@ func (c *scontext) argList(args [][]byte) ([]interface{}, error) {
|
||||
if v, ok := fields[string(av)]; ok {
|
||||
switch v[0] {
|
||||
case '[', '{':
|
||||
vars[i] = v
|
||||
if isJsonScalarArray(v) {
|
||||
vars[i] = jsonListToValues(v)
|
||||
} else {
|
||||
vars[i] = v
|
||||
}
|
||||
|
||||
default:
|
||||
var val interface{}
|
||||
if err := json.Unmarshal(v, &val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vars[i] = val
|
||||
}
|
||||
|
||||
@ -163,6 +171,38 @@ func escSQuote(b []byte) []byte {
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func isJsonScalarArray(b []byte) bool {
|
||||
if b[0] != '[' || b[len(b)-1] != ']' {
|
||||
return false
|
||||
}
|
||||
for i := range b {
|
||||
switch b[i] {
|
||||
case '{':
|
||||
return false
|
||||
case '[', ' ', '\t', '\n':
|
||||
continue
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func jsonListToValues(b []byte) []byte {
|
||||
s := 0
|
||||
for i := 1; i < len(b)-1; i++ {
|
||||
if b[i] == '"' && s%2 == 0 {
|
||||
b[i] = '\''
|
||||
}
|
||||
if b[i] == '\\' {
|
||||
s++
|
||||
} else {
|
||||
s = 0
|
||||
}
|
||||
}
|
||||
return b[1 : len(b)-1]
|
||||
}
|
||||
|
||||
func argErr(name string) error {
|
||||
return fmt.Errorf("query requires variable '%s' to be set", name)
|
||||
}
|
||||
|
@ -239,8 +239,6 @@ func (al *List) save(item Item) error {
|
||||
qd := &schema.QueryDocument{}
|
||||
|
||||
if err := qd.Parse(item.Query); err != nil {
|
||||
fmt.Println("##", item.Query)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -248,8 +246,6 @@ func (al *List) save(item Item) error {
|
||||
query := buf.String()
|
||||
buf.Reset()
|
||||
|
||||
// fmt.Println(">", query)
|
||||
|
||||
item.Name = QueryName(query)
|
||||
item.key = strings.ToLower(item.Name)
|
||||
|
||||
|
@ -1027,9 +1027,9 @@ func (c *compilerContext) renderOp(ex *qcode.Exp, ti *DBTableInfo) error {
|
||||
case qcode.OpLesserThan:
|
||||
io.WriteString(c.w, `<`)
|
||||
case qcode.OpIn:
|
||||
io.WriteString(c.w, `IN`)
|
||||
io.WriteString(c.w, `= ANY`)
|
||||
case qcode.OpNotIn:
|
||||
io.WriteString(c.w, `NOT IN`)
|
||||
io.WriteString(c.w, `!= ANY`)
|
||||
case qcode.OpLike:
|
||||
io.WriteString(c.w, `LIKE`)
|
||||
case qcode.OpNotLike:
|
||||
@ -1175,6 +1175,16 @@ func (c *compilerContext) renderVal(ex *qcode.Exp, vars map[string]string, col *
|
||||
io.WriteString(c.w, `)`)
|
||||
case ok:
|
||||
squoted(c.w, val)
|
||||
case ex.Op == qcode.OpIn || ex.Op == qcode.OpNotIn:
|
||||
io.WriteString(c.w, ` (string_to_array('{{`)
|
||||
io.WriteString(c.w, ex.Val)
|
||||
io.WriteString(c.w, `}}', ',')`)
|
||||
|
||||
io.WriteString(c.w, ` :: `)
|
||||
io.WriteString(c.w, col.Type)
|
||||
io.WriteString(c.w, `[])`)
|
||||
return
|
||||
|
||||
default:
|
||||
io.WriteString(c.w, ` '{{`)
|
||||
io.WriteString(c.w, ex.Val)
|
||||
|
@ -344,17 +344,17 @@ func (com *Compiler) compileQuery(qc *QCode, op *Operation, role string) error {
|
||||
|
||||
case QTInsert:
|
||||
if trv.insert.block {
|
||||
return fmt.Errorf("insert blocked: %s", field.Name)
|
||||
return fmt.Errorf("%s, insert blocked: %s", role, field.Name)
|
||||
}
|
||||
|
||||
case QTUpdate:
|
||||
if trv.update.block {
|
||||
return fmt.Errorf("update blocked: %s", field.Name)
|
||||
return fmt.Errorf("%s, update blocked: %s", role, field.Name)
|
||||
}
|
||||
|
||||
case QTDelete:
|
||||
if trv.delete.block {
|
||||
return fmt.Errorf("delete blocked: %s", field.Name)
|
||||
return fmt.Errorf("%s, delete blocked: %s", role, field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1030,10 +1030,15 @@ func setListVal(ex *Exp, node *Node) {
|
||||
case NodeFloat:
|
||||
ex.ListType = ValFloat
|
||||
}
|
||||
} else {
|
||||
ex.Val = node.Val
|
||||
return
|
||||
}
|
||||
|
||||
for i := range node.Children {
|
||||
ex.ListVal = append(ex.ListVal, node.Children[i].Val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func setWhereColName(ex *Exp, node *Node) {
|
||||
|
Reference in New Issue
Block a user