gendry icon indicating copy to clipboard operation
gendry copied to clipboard

support fields linked with ops

Open Guojunzhou-git opened this issue 2 years ago • 4 comments

map with key foo> instead of foo > got field="foo>" operator="=", then where condition is foo>=.

builder.BuildSelect(map[string]interface{}{
    "foo>": "bar"
})

got

SELECT * FROM tb WHERE (foo>=?)"

when no space in key, not default field=key and operator="=", but try to parse fileds linked with ops, such as foo>,foo>=,foo<,foo<=,foo<>,foo!=,foo=

Guojunzhou-git avatar Feb 13 '23 08:02 Guojunzhou-git

可以讨论下必要性,我个人觉得这个没多大必要:

  1. 大多数时候用的都是等于比较,即 "a": 1。如果合入这个pr之后,所有的等于比较都要增加额外的负担来检查key里是否包涵比较符号,对性能有一定影响
  2. 用户只要知道中间要打个空格,是不是以后就完全用不到这个feature了

caibirdme avatar Feb 13 '23 11:02 caibirdme

可以讨论下必要性,我个人觉得这个没多大必要:

  1. 大多数时候用的都是等于比较,即 "a": 1。如果合入这个pr之后,所有的等于比较都要增加额外的负担来检查key里是否包涵比较符号,对性能有一定影响
  2. 用户只要知道中间要打个空格,是不是以后就完全用不到这个feature了

个人建议哈:

  1. 比起 a>= 解析为 a>== 的 sql 错误来讲,b>解析为 b>= 的表现会比较难以发现。引入此 pr 后,使用起来会更友好些。
  2. opCanLinkedWithField涉及此问题的运算符只有7个:4个2字符运算符(将导致sql错误)和3个1字符运算符(将导致语义上的变化),对性能的影响不是很大。

综上,还是建议能更多的考虑易用和友好

Guojunzhou-git avatar Feb 20 '23 03:02 Guojunzhou-git

func splitKey(key string, val interface{}) (field string, operator string, err error) {
	key = strings.Trim(key, " ")
	if "" == key {
		err = errSplitEmptyKey
		return
	}
	idx := strings.IndexByte(key, ' ')
	if idx == -1 {
		field = key
		operator = "="
		if isFieldContainOp(field) {
			field, operator = splitKeyNoSpace(field)
		}
		if reflect.ValueOf(val).Kind() == reflect.Slice {
			operator = "in"
		}
	} else {
		field = key[:idx]
		operator = strings.Trim(key[idx+1:], " ")
		operator = removeInnerSpace(operator)
	}
	return
}

func isFieldContainOp(field string) (contains bool) {
	if field == "" {
		return
	}
	ecof := field[len(field)-1:]
	contains = ecof == opEq || ecof == opLt || ecof == opGt
	return
}
`

Guojunzhou-git avatar Feb 20 '23 10:02 Guojunzhou-git

可以尝试 isFieldContainOp 判定下是否需要

Guojunzhou-git avatar Feb 20 '23 10:02 Guojunzhou-git