本文主要研究一下dbsync的Criteriongit
//Criterion represents criterion type Criterion fmt.Stringer
Criterion是一個fmt.Stringer類型
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 criterion func NewBetween(from, to int) Criterion { return &between{from: from, to: to} }
between定義from、to兩個屬性
type lessOrEqual struct { value int } func (c lessOrEqual) String() string { return fmt.Sprintf(" <= %v", c.value) } //NewLessOrEqual creates less of equal criterion func NewLessOrEqual(value int) Criterion { return &lessOrEqual{value} }
lessOrEqual定義了value屬性,表達式爲
<=
type greaterThan struct { value int } func (c greaterThan) String() string { return fmt.Sprintf(" > %v", c.value) } //NewGraterThan creates grater than criterion func NewGraterThan(value int) Criterion { return &greaterThan{value} }
greaterThan定義了value屬性,表達式爲
>
type greaterOrEqual struct { value int } func (c greaterOrEqual) String() string { return fmt.Sprintf(" >= %v", c.value) } //NewGraterOrEqual creates grater or equal criterion func NewGraterOrEqual(value int) Criterion { return &greaterOrEqual{value} }
greaterOrEqual定義了value屬性,表達式爲
>=
//ToCriterion converts a kv pair to a criterion func 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方法進行轉換。github