session_query.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. default:
  37. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  38. }
  39. // time type
  40. case reflect.Struct:
  41. if aa.ConvertibleTo(core.TimeType) {
  42. str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
  43. } else {
  44. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  45. }
  46. case reflect.Bool:
  47. str = strconv.FormatBool(vv.Bool())
  48. case reflect.Complex128, reflect.Complex64:
  49. str = fmt.Sprintf("%v", vv.Complex())
  50. /* TODO: unsupported types below
  51. case reflect.Map:
  52. case reflect.Ptr:
  53. case reflect.Uintptr:
  54. case reflect.UnsafePointer:
  55. case reflect.Chan, reflect.Func, reflect.Interface:
  56. */
  57. default:
  58. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  59. }
  60. return
  61. }
  62. func value2String(rawValue *reflect.Value) (data string, err error) {
  63. data, err = reflect2value(rawValue)
  64. if err != nil {
  65. return
  66. }
  67. return
  68. }
  69. func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
  70. result := make(map[string]string)
  71. scanResultContainers := make([]interface{}, len(fields))
  72. for i := 0; i < len(fields); i++ {
  73. var scanResultContainer interface{}
  74. scanResultContainers[i] = &scanResultContainer
  75. }
  76. if err := rows.Scan(scanResultContainers...); err != nil {
  77. return nil, err
  78. }
  79. for ii, key := range fields {
  80. rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
  81. // if row is null then as empty string
  82. if rawValue.Interface() == nil {
  83. result[key] = ""
  84. continue
  85. }
  86. if data, err := value2String(&rawValue); err == nil {
  87. result[key] = data
  88. } else {
  89. return nil, err
  90. }
  91. }
  92. return result, nil
  93. }
  94. func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
  95. fields, err := rows.Columns()
  96. if err != nil {
  97. return nil, err
  98. }
  99. for rows.Next() {
  100. result, err := row2mapStr(rows, fields)
  101. if err != nil {
  102. return nil, err
  103. }
  104. resultsSlice = append(resultsSlice, result)
  105. }
  106. return resultsSlice, nil
  107. }
  108. // QueryString runs a raw sql and return records as []map[string]string
  109. func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
  110. if session.isAutoClose {
  111. defer session.Close()
  112. }
  113. rows, err := session.queryRows(sqlStr, args...)
  114. if err != nil {
  115. return nil, err
  116. }
  117. defer rows.Close()
  118. return rows2Strings(rows)
  119. }
  120. func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
  121. resultsMap = make(map[string]interface{}, len(fields))
  122. scanResultContainers := make([]interface{}, len(fields))
  123. for i := 0; i < len(fields); i++ {
  124. var scanResultContainer interface{}
  125. scanResultContainers[i] = &scanResultContainer
  126. }
  127. if err := rows.Scan(scanResultContainers...); err != nil {
  128. return nil, err
  129. }
  130. for ii, key := range fields {
  131. resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface()
  132. }
  133. return
  134. }
  135. func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
  136. fields, err := rows.Columns()
  137. if err != nil {
  138. return nil, err
  139. }
  140. for rows.Next() {
  141. result, err := row2mapInterface(rows, fields)
  142. if err != nil {
  143. return nil, err
  144. }
  145. resultsSlice = append(resultsSlice, result)
  146. }
  147. return resultsSlice, nil
  148. }
  149. // QueryInterface runs a raw sql and return records as []map[string]interface{}
  150. func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
  151. if session.isAutoClose {
  152. defer session.Close()
  153. }
  154. rows, err := session.queryRows(sqlStr, args...)
  155. if err != nil {
  156. return nil, err
  157. }
  158. defer rows.Close()
  159. return rows2Interfaces(rows)
  160. }