序
本文次要钻研一下dbsync的Criterion
Criterion
//Criterion represents criteriontype Criterion fmt.Stringer
Criterion是一个fmt.Stringer类型
between
type between struct { from int to int}func (b between) String() string { return fmt.Sprintf("BETWEEN %v AND %v", b.from, b.to)}//NewBetween creates new betwee criterionfunc NewBetween(from, to int) Criterion { return &between{from: from, to: to}}
between定义from、to两个属性
lessOrEqual
type lessOrEqual struct { value int}func (c lessOrEqual) String() string { return fmt.Sprintf(" <= %v", c.value)}//NewLessOrEqual creates less of equal criterionfunc NewLessOrEqual(value int) Criterion { return &lessOrEqual{value}}
lessOrEqual定义了value属性,表达式为<=
greaterThan
type greaterThan struct { value int}func (c greaterThan) String() string { return fmt.Sprintf(" > %v", c.value)}//NewGraterThan creates grater than criterionfunc NewGraterThan(value int) Criterion { return &greaterThan{value}}
greaterThan定义了value属性,表达式为>
greaterOrEqual
type greaterOrEqual struct { value int}func (c greaterOrEqual) String() string { return fmt.Sprintf(" >= %v", c.value)}//NewGraterOrEqual creates grater or equal criterionfunc NewGraterOrEqual(value int) Criterion { return &greaterOrEqual{value}}
greaterOrEqual定义了value属性,表达式为>=
ToCriterion
//ToCriterion converts a kv pair to a criterionfunc ToCriterion(k string, v interface{}) string { if greaterOrEqual, ok := v.(*greaterOrEqual); ok { return fmt.Sprintf("%v >= %v", k, greaterOrEqual.value) } else if greaterThan, ok := v.(*greaterThan); ok { return fmt.Sprintf("%v > %v", k, greaterThan.value) } else if lessOrEqual, ok := v.(*lessOrEqual); ok { return fmt.Sprintf("%v <= %v", k, lessOrEqual.value) } else if between, ok := v.(*between); ok { return fmt.Sprintf("%v BETWEEN %v AND %v", k, between.from, between.to) } else if toolbox.IsSlice(v) { aSlice := toolbox.AsSlice(v) var whereValues = make([]string, 0) for _, item := range aSlice { if intValue, err := toolbox.ToInt(item); err == nil { whereValues = append(whereValues, fmt.Sprintf(`%v`, intValue)) } else { itemLiteral := toolbox.AsString(item) if strings.HasPrefix(itemLiteral, "(") && strings.HasSuffix(itemLiteral, ")") { whereValues = append(whereValues, fmt.Sprintf(`%v`, item)) } else { whereValues = append(whereValues, fmt.Sprintf(`'%v'`, item)) } } } return fmt.Sprintf("%v IN(%v)", k, strings.Join(whereValues, ",")) } else if _, err := toolbox.ToInt(v); err == nil { return fmt.Sprintf("%v = %v", k, v) } else { literal := strings.TrimSpace(toolbox.AsString(v)) lowerLiteral := strings.ToLower(literal) if strings.Contains(literal, ">") || strings.Contains(literal, "<") || strings.Contains(lowerLiteral, " null") { return fmt.Sprintf("%v %v", k, v) } return fmt.Sprintf("%v = '%v'", k, v) }}
ToCriterion办法判断v是否是greaterOrEqual、greaterThan、lessOrEqual、between类型做对应的转换,针对IsSlice的做专门的拼接解决
小结
dbsync的Criterion是一个fmt.Stringer类型,它内置了greaterOrEqual、greaterThan、lessOrEqual、between类型,并提供ToCriterion办法进行转换。
doc
- dbsync