query.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package search
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. )
  7. const (
  8. // FromQueryTag tag标记
  9. FromQueryTag = "search"
  10. // OrderDefaultTag tag标记
  11. DefaultTag = "default"
  12. // Mysql 数据库标识
  13. Mysql = "mysql"
  14. // Postgres 数据库标识
  15. Postgres = "postgres"
  16. )
  17. // ResolveSearchQuery 解析
  18. /**
  19. * exact / iexact 等于
  20. * contains / icontains 包含
  21. * gt / gte 大于 / 大于等于
  22. * lt / lte 小于 / 小于等于
  23. * startswith / istartswith 以…起始
  24. * endswith / iendswith 以…结束
  25. * in
  26. * isnull
  27. * order 排序 e.g. order[key]=desc order[key]=asc
  28. */
  29. func ResolveSearchQuery(driver string, q interface{}, condition Condition) {
  30. qType := reflect.TypeOf(q)
  31. qValue := reflect.ValueOf(q)
  32. var tag string
  33. var ok bool
  34. var t *resolveSearchTag
  35. for i := 0; i < qType.NumField(); i++ {
  36. tag, ok = "", false
  37. tag, ok = qType.Field(i).Tag.Lookup(FromQueryTag)
  38. if !ok {
  39. //递归调用
  40. ResolveSearchQuery(driver, qValue.Field(i).Interface(), condition)
  41. continue
  42. }
  43. switch tag {
  44. case "-":
  45. continue
  46. }
  47. defaultTag, defaultOk := qType.Field(i).Tag.Lookup(DefaultTag)
  48. if qValue.Field(i).IsZero() && !defaultOk {
  49. continue
  50. }
  51. t = makeTag(tag)
  52. //解析
  53. switch t.Type {
  54. case "left":
  55. //左关联
  56. join := condition.SetJoinOn(t.Type, fmt.Sprintf(
  57. "left join `%s` on `%s`.`%s` = `%s`.`%s`",
  58. t.Join,
  59. t.Join,
  60. t.On[0],
  61. t.Table,
  62. t.On[1],
  63. ))
  64. ResolveSearchQuery(driver, qValue.Field(i).Interface(), join)
  65. case "exact", "iexact":
  66. condition.SetWhere(fmt.Sprintf("`%s`.`%s` = ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  67. case "contains":
  68. condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String() + "%"})
  69. case "orcontains":
  70. condition.SetOrContains(fmt.Sprintf("`%s`.`%s` like ", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String() + "%"})
  71. case "gt":
  72. condition.SetWhere(fmt.Sprintf("`%s`.`%s` > ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  73. case "gte":
  74. condition.SetWhere(fmt.Sprintf("`%s`.`%s` >= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  75. case "lt":
  76. condition.SetWhere(fmt.Sprintf("`%s`.`%s` < ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  77. case "lte":
  78. condition.SetWhere(fmt.Sprintf("`%s`.`%s` <= ?", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  79. case "startswith":
  80. condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{qValue.Field(i).String() + "%"})
  81. case "endswith":
  82. condition.SetWhere(fmt.Sprintf("`%s`.`%s` like ?", t.Table, t.Column), []interface{}{"%" + qValue.Field(i).String()})
  83. case "in":
  84. condition.SetWhere(fmt.Sprintf("`%s`.`%s` in (?)", t.Table, t.Column), []interface{}{qValue.Field(i).Interface()})
  85. case "isnull":
  86. if !(qValue.Field(i).IsZero() && qValue.Field(i).IsNil()) {
  87. condition.SetWhere(fmt.Sprintf("`%s`.`%s` isnull", t.Table, t.Column), make([]interface{}, 0))
  88. }
  89. case "order":
  90. switch strings.ToLower(qValue.Field(i).String()) {
  91. case "desc", "asc":
  92. condition.SetOrder(fmt.Sprintf("`%s`.`%s` %s", t.Table, t.Column, qValue.Field(i).String()))
  93. default:
  94. condition.SetOrder(fmt.Sprintf("`%s`.`%s` %s", t.Table, t.Column, defaultTag))
  95. }
  96. }
  97. }
  98. }