session_query.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2017 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "time"
  10. "github.com/xormplus/core"
  11. )
  12. // Query runs a raw sql and return records as []map[string][]byte
  13. func (session *Session) QueryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
  14. if session.isAutoClose {
  15. defer session.Close()
  16. }
  17. return session.queryBytes(sqlStr, args...)
  18. }
  19. func reflect2value(rawValue *reflect.Value) (str string, err error) {
  20. aa := reflect.TypeOf((*rawValue).Interface())
  21. vv := reflect.ValueOf((*rawValue).Interface())
  22. switch aa.Kind() {
  23. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  24. str = strconv.FormatInt(vv.Int(), 10)
  25. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  26. str = strconv.FormatUint(vv.Uint(), 10)
  27. case reflect.Float32, reflect.Float64:
  28. str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
  29. case reflect.String:
  30. str = vv.String()
  31. case reflect.Array, reflect.Slice:
  32. switch aa.Elem().Kind() {
  33. case reflect.Uint8:
  34. data := rawValue.Interface().([]byte)
  35. str = string(data)
  36. if str == "\x00" {
  37. str = "0"
  38. }
  39. default:
  40. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  41. }
  42. // time type
  43. case reflect.Struct:
  44. if aa.ConvertibleTo(core.TimeType) {
  45. str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
  46. } else {
  47. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  48. }
  49. case reflect.Bool:
  50. str = strconv.FormatBool(vv.Bool())
  51. case reflect.Complex128, reflect.Complex64:
  52. str = fmt.Sprintf("%v", vv.Complex())
  53. /* TODO: unsupported types below
  54. case reflect.Map:
  55. case reflect.Ptr:
  56. case reflect.Uintptr:
  57. case reflect.UnsafePointer:
  58. case reflect.Chan, reflect.Func, reflect.Interface:
  59. */
  60. default:
  61. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  62. }
  63. return
  64. }
  65. func value2String(rawValue *reflect.Value) (data string, err error) {
  66. data, err = reflect2value(rawValue)
  67. if err != nil {
  68. return
  69. }
  70. return
  71. }
  72. func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
  73. result := make(map[string]string)
  74. scanResultContainers := make([]interface{}, len(fields))
  75. for i := 0; i < len(fields); i++ {
  76. var scanResultContainer interface{}
  77. scanResultContainers[i] = &scanResultContainer
  78. }
  79. if err := rows.Scan(scanResultContainers...); err != nil {
  80. return nil, err
  81. }
  82. for ii, key := range fields {
  83. rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
  84. // if row is null then as empty string
  85. if rawValue.Interface() == nil {
  86. result[key] = ""
  87. continue
  88. }
  89. if data, err := value2String(&rawValue); err == nil {
  90. result[key] = data
  91. } else {
  92. return nil, err
  93. }
  94. }
  95. return result, nil
  96. }
  97. func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
  98. fields, err := rows.Columns()
  99. if err != nil {
  100. return nil, err
  101. }
  102. for rows.Next() {
  103. result, err := row2mapStr(rows, fields)
  104. if err != nil {
  105. return nil, err
  106. }
  107. resultsSlice = append(resultsSlice, result)
  108. }
  109. return resultsSlice, nil
  110. }
  111. // QueryString runs a raw sql and return records as []map[string]string
  112. func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
  113. if session.isAutoClose {
  114. defer session.Close()
  115. }
  116. rows, err := session.queryRows(sqlStr, args...)
  117. if err != nil {
  118. return nil, err
  119. }
  120. defer rows.Close()
  121. return rows2Strings(rows)
  122. }
  123. func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
  124. resultsMap = make(map[string]interface{}, len(fields))
  125. scanResultContainers := make([]interface{}, len(fields))
  126. for i := 0; i < len(fields); i++ {
  127. var scanResultContainer interface{}
  128. scanResultContainers[i] = &scanResultContainer
  129. }
  130. if err := rows.Scan(scanResultContainers...); err != nil {
  131. return nil, err
  132. }
  133. for ii, key := range fields {
  134. resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface()
  135. }
  136. return
  137. }
  138. func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
  139. fields, err := rows.Columns()
  140. if err != nil {
  141. return nil, err
  142. }
  143. for rows.Next() {
  144. result, err := row2mapInterface(rows, fields)
  145. if err != nil {
  146. return nil, err
  147. }
  148. resultsSlice = append(resultsSlice, result)
  149. }
  150. return resultsSlice, nil
  151. }
  152. // QueryInterface runs a raw sql and return records as []map[string]interface{}
  153. func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
  154. if session.isAutoClose {
  155. defer session.Close()
  156. }
  157. rows, err := session.queryRows(sqlStr, args...)
  158. if err != nil {
  159. return nil, err
  160. }
  161. defer rows.Close()
  162. return rows2Interfaces(rows)
  163. }