query.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package hqi
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "reflect"
  6. "strings"
  7. )
  8. var (
  9. ErrNotImplemented = errors.New("Not implemented")
  10. )
  11. const (
  12. //ResultCount get the number of entries instead of Content
  13. ResultCount = iota
  14. //ResultOne get one result
  15. ResultOne
  16. //ResultList get a list of results (even one)
  17. ResultList
  18. //SortAsc sort smaller to bigger
  19. SortAsc = iota
  20. //SortDesc sort bigger to smaller
  21. SortDesc
  22. )
  23. //Field common field type
  24. type (
  25. Field struct {
  26. Name string
  27. Value interface{}
  28. }
  29. M map[string]interface{}
  30. Query struct {
  31. driver Driver
  32. }
  33. )
  34. func NewQuery(driver Driver) Query {
  35. if driver == nil {
  36. panic("Driver is nil")
  37. }
  38. return Query{driver}
  39. }
  40. //Find Initiates a query builder
  41. func (q *Query) Find(samples ...interface{}) SecondStage {
  42. // Convert samples to hql.M
  43. samplesMap := []M{}
  44. for _, sample := range samples {
  45. var cur M
  46. switch t := sample.(type) {
  47. case M:
  48. cur = t
  49. case map[string]interface{}:
  50. cur = t
  51. case string:
  52. cur = M{}
  53. json.Unmarshal([]byte(t), &cur)
  54. default:
  55. //TODO: do own conversion
  56. cur = s2m(sample)
  57. /*cur = M{}
  58. data, _ := json.Marshal(sample)
  59. json.Unmarshal(data, &cur)*/
  60. }
  61. samplesMap = append(samplesMap, cur)
  62. }
  63. //Convert samples to map[string]interface{}
  64. b := Builder{data: QueryParam{Samples: samplesMap}, driver: q.driver}
  65. return &b
  66. }
  67. func (q *Query) Schema(sample interface{}) error {
  68. return q.driver.Schema(sample)
  69. }
  70. func (q *Query) Insert(objs ...interface{}) error {
  71. return q.driver.Insert(objs...)
  72. }
  73. // Convert struct to M
  74. func s2m(obj interface{}) M {
  75. var ret = M{}
  76. //objTyp := reflect.TypeOf(obj)
  77. objVal := reflect.ValueOf(obj)
  78. for i := 0; i < objVal.Type().NumField(); i++ {
  79. fieldTyp := objVal.Type().Field(i)
  80. value := objVal.Field(i)
  81. valI := value.Interface()
  82. fName := fieldTyp.Name
  83. omitEmpty := false
  84. // PARSE struct TAGS
  85. tagStr, ok := fieldTyp.Tag.Lookup("hqi")
  86. if ok {
  87. opts := strings.Split(tagStr, ",")
  88. if opts[0] != "" {
  89. fName = opts[0]
  90. }
  91. if len(opts) > 1 && opts[1] == "omitempty" {
  92. omitEmpty = true
  93. }
  94. }
  95. // Check nil or zero if omitEmpty
  96. if valI == nil || (isZero(valI) && omitEmpty) {
  97. continue
  98. }
  99. valKind := reflect.TypeOf(valI).Kind()
  100. switch valKind {
  101. case reflect.Slice:
  102. var s = []M{} // new slice
  103. for si := 0; si < value.Len(); si++ {
  104. s = append(s, s2m(value.Index(si).Interface()))
  105. }
  106. ret[fName] = s
  107. case reflect.Map:
  108. var m = M{}
  109. for _, k := range value.MapKeys() {
  110. m[k.String()] = value.MapIndex(k).Interface()
  111. }
  112. ret[fName] = m
  113. case reflect.Struct:
  114. ret[fName] = s2m(valI) // recursive
  115. default:
  116. ret[fName] = valI
  117. }
  118. }
  119. return ret
  120. }
  121. func isZero(x interface{}) bool {
  122. return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
  123. }