http urls monitor.

fetch.go 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining
  4. // a copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to
  8. // permit persons to whom the Software is furnished to do so, subject to
  9. // the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be
  12. // included in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. package sqlbuilder
  22. import (
  23. "reflect"
  24. "upper.io/db.v3"
  25. "upper.io/db.v3/lib/reflectx"
  26. )
  27. type hasConvertValues interface {
  28. ConvertValues(values []interface{}) []interface{}
  29. }
  30. var mapper = reflectx.NewMapper("db")
  31. // fetchRow receives a *sql.Rows value and tries to map all the rows into a
  32. // single struct given by the pointer `dst`.
  33. func fetchRow(iter *iterator, dst interface{}) error {
  34. var columns []string
  35. var err error
  36. rows := iter.cursor
  37. dstv := reflect.ValueOf(dst)
  38. if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
  39. return ErrExpectingPointer
  40. }
  41. itemV := dstv.Elem()
  42. if columns, err = rows.Columns(); err != nil {
  43. return err
  44. }
  45. reset(dst)
  46. next := rows.Next()
  47. if next == false {
  48. if err = rows.Err(); err != nil {
  49. return err
  50. }
  51. return db.ErrNoMoreRows
  52. }
  53. itemT := itemV.Type()
  54. item, err := fetchResult(iter, itemT, columns)
  55. if err != nil {
  56. return err
  57. }
  58. if itemT.Kind() == reflect.Ptr {
  59. itemV.Set(item)
  60. } else {
  61. itemV.Set(reflect.Indirect(item))
  62. }
  63. return nil
  64. }
  65. // fetchRows receives a *sql.Rows value and tries to map all the rows into a
  66. // slice of structs given by the pointer `dst`.
  67. func fetchRows(iter *iterator, dst interface{}) error {
  68. var err error
  69. rows := iter.cursor
  70. defer rows.Close()
  71. // Destination.
  72. dstv := reflect.ValueOf(dst)
  73. if dstv.IsNil() || dstv.Kind() != reflect.Ptr {
  74. return ErrExpectingPointer
  75. }
  76. if dstv.Elem().Kind() != reflect.Slice {
  77. return ErrExpectingSlicePointer
  78. }
  79. if dstv.Kind() != reflect.Ptr || dstv.Elem().Kind() != reflect.Slice || dstv.IsNil() {
  80. return ErrExpectingSliceMapStruct
  81. }
  82. var columns []string
  83. if columns, err = rows.Columns(); err != nil {
  84. return err
  85. }
  86. slicev := dstv.Elem()
  87. itemT := slicev.Type().Elem()
  88. reset(dst)
  89. for rows.Next() {
  90. item, err := fetchResult(iter, itemT, columns)
  91. if err != nil {
  92. return err
  93. }
  94. if itemT.Kind() == reflect.Ptr {
  95. slicev = reflect.Append(slicev, item)
  96. } else {
  97. slicev = reflect.Append(slicev, reflect.Indirect(item))
  98. }
  99. }
  100. dstv.Elem().Set(slicev)
  101. return nil
  102. }
  103. func fetchResult(iter *iterator, itemT reflect.Type, columns []string) (reflect.Value, error) {
  104. var item reflect.Value
  105. var err error
  106. rows := iter.cursor
  107. objT := itemT
  108. switch objT.Kind() {
  109. case reflect.Map:
  110. item = reflect.MakeMap(objT)
  111. case reflect.Struct:
  112. item = reflect.New(objT)
  113. case reflect.Ptr:
  114. objT = itemT.Elem()
  115. if objT.Kind() != reflect.Struct {
  116. return item, ErrExpectingMapOrStruct
  117. }
  118. item = reflect.New(objT)
  119. default:
  120. return item, ErrExpectingMapOrStruct
  121. }
  122. switch objT.Kind() {
  123. case reflect.Struct:
  124. values := make([]interface{}, len(columns))
  125. typeMap := mapper.TypeMap(itemT)
  126. fieldMap := typeMap.Names
  127. for i, k := range columns {
  128. fi, ok := fieldMap[k]
  129. if !ok {
  130. values[i] = new(interface{})
  131. continue
  132. }
  133. // Check for deprecated jsonb tag.
  134. if _, hasJSONBTag := fi.Options["jsonb"]; hasJSONBTag {
  135. return item, errDeprecatedJSONBTag
  136. }
  137. f := reflectx.FieldByIndexes(item, fi.Index)
  138. values[i] = f.Addr().Interface()
  139. if u, ok := values[i].(db.Unmarshaler); ok {
  140. values[i] = scanner{u}
  141. }
  142. }
  143. if converter, ok := iter.sess.(hasConvertValues); ok {
  144. values = converter.ConvertValues(values)
  145. }
  146. if err = rows.Scan(values...); err != nil {
  147. return item, err
  148. }
  149. case reflect.Map:
  150. columns, err := rows.Columns()
  151. if err != nil {
  152. return item, err
  153. }
  154. values := make([]interface{}, len(columns))
  155. for i := range values {
  156. if itemT.Elem().Kind() == reflect.Interface {
  157. values[i] = new(interface{})
  158. } else {
  159. values[i] = reflect.New(itemT.Elem()).Interface()
  160. }
  161. }
  162. if err = rows.Scan(values...); err != nil {
  163. return item, err
  164. }
  165. for i, column := range columns {
  166. item.SetMapIndex(reflect.ValueOf(column), reflect.Indirect(reflect.ValueOf(values[i])))
  167. }
  168. }
  169. return item, nil
  170. }
  171. func reset(data interface{}) error {
  172. // Resetting element.
  173. v := reflect.ValueOf(data).Elem()
  174. t := v.Type()
  175. var z reflect.Value
  176. switch v.Kind() {
  177. case reflect.Slice:
  178. z = reflect.MakeSlice(t, 0, v.Cap())
  179. default:
  180. z = reflect.Zero(t)
  181. }
  182. v.Set(z)
  183. return nil
  184. }