builder.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package builderx
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. "github.com/go-xorm/builder"
  7. )
  8. const dbTag = "db"
  9. // NewEq wraps builder.Eq.
  10. func NewEq(in interface{}) builder.Eq {
  11. return builder.Eq(ToMap(in))
  12. }
  13. // NewGt wraps builder.Gt.
  14. func NewGt(in interface{}) builder.Gt {
  15. return builder.Gt(ToMap(in))
  16. }
  17. // ToMap converts interface into map.
  18. func ToMap(in interface{}) map[string]interface{} {
  19. out := make(map[string]interface{})
  20. v := reflect.ValueOf(in)
  21. if v.Kind() == reflect.Ptr {
  22. v = v.Elem()
  23. }
  24. // we only accept structs
  25. if v.Kind() != reflect.Struct {
  26. panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
  27. }
  28. typ := v.Type()
  29. for i := 0; i < v.NumField(); i++ {
  30. // gets us a StructField
  31. fi := typ.Field(i)
  32. if tagv := fi.Tag.Get(dbTag); tagv != "" {
  33. // set key of map to value in struct field
  34. val := v.Field(i)
  35. zero := reflect.Zero(val.Type()).Interface()
  36. current := val.Interface()
  37. if reflect.DeepEqual(current, zero) {
  38. continue
  39. }
  40. out[tagv] = current
  41. }
  42. }
  43. return out
  44. }
  45. // FieldNames returns field names from given in.
  46. // deprecated: use RawFieldNames instead automatically while model generating after goctl version v1.1.0
  47. func FieldNames(in interface{}) []string {
  48. out := make([]string, 0)
  49. v := reflect.ValueOf(in)
  50. if v.Kind() == reflect.Ptr {
  51. v = v.Elem()
  52. }
  53. // we only accept structs
  54. if v.Kind() != reflect.Struct {
  55. panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
  56. }
  57. typ := v.Type()
  58. for i := 0; i < v.NumField(); i++ {
  59. // gets us a StructField
  60. fi := typ.Field(i)
  61. if tagv := fi.Tag.Get(dbTag); tagv != "" {
  62. out = append(out, tagv)
  63. } else {
  64. out = append(out, fi.Name)
  65. }
  66. }
  67. return out
  68. }
  69. // RawFieldNames converts golang struct field into slice string.
  70. func RawFieldNames(in interface{}, postgresSql ...bool) []string {
  71. out := make([]string, 0)
  72. v := reflect.ValueOf(in)
  73. if v.Kind() == reflect.Ptr {
  74. v = v.Elem()
  75. }
  76. var pg bool
  77. if len(postgresSql) > 0 {
  78. pg = postgresSql[0]
  79. }
  80. // we only accept structs
  81. if v.Kind() != reflect.Struct {
  82. panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
  83. }
  84. typ := v.Type()
  85. for i := 0; i < v.NumField(); i++ {
  86. // gets us a StructField
  87. fi := typ.Field(i)
  88. if tagv := fi.Tag.Get(dbTag); tagv != "" {
  89. if pg {
  90. out = append(out, tagv)
  91. } else {
  92. out = append(out, fmt.Sprintf("`%s`", tagv))
  93. }
  94. } else {
  95. if pg {
  96. out = append(out, fi.Name)
  97. } else {
  98. out = append(out, fmt.Sprintf("`%s`", fi.Name))
  99. }
  100. }
  101. }
  102. return out
  103. }
  104. // PostgreSqlJoin concatenates the given elements into a string.
  105. func PostgreSqlJoin(elems []string) string {
  106. b := new(strings.Builder)
  107. for index, e := range elems {
  108. b.WriteString(fmt.Sprintf("%s = $%d, ", e, index+2))
  109. }
  110. if b.Len() == 0 {
  111. return b.String()
  112. }
  113. return b.String()[0 : b.Len()-2]
  114. }