session_query.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. "strings"
  10. "time"
  11. "github.com/go-xorm/builder"
  12. "github.com/xormplus/core"
  13. )
  14. // QueryBytes runs a raw sql and return records as []map[string][]byte
  15. func (session *Session) QueryBytes(sqlorArgs ...interface{}) ([]map[string][]byte, error) {
  16. if session.isAutoClose {
  17. defer session.Close()
  18. }
  19. var sqlStr string
  20. var args []interface{}
  21. if len(sqlorArgs) == 0 {
  22. if session.statement.RawSQL != "" {
  23. sqlStr = session.statement.RawSQL
  24. args = session.statement.RawParams
  25. } else {
  26. if len(session.statement.TableName()) <= 0 {
  27. return nil, ErrTableNotFound
  28. }
  29. var columnStr = session.statement.ColumnStr
  30. if len(session.statement.selectStr) > 0 {
  31. columnStr = session.statement.selectStr
  32. } else {
  33. if session.statement.JoinStr == "" {
  34. if columnStr == "" {
  35. if session.statement.GroupByStr != "" {
  36. columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
  37. } else {
  38. columnStr = session.statement.genColumnStr()
  39. }
  40. }
  41. } else {
  42. if columnStr == "" {
  43. if session.statement.GroupByStr != "" {
  44. columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
  45. } else {
  46. columnStr = "*"
  47. }
  48. }
  49. }
  50. if columnStr == "" {
  51. columnStr = "*"
  52. }
  53. }
  54. condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
  55. if err != nil {
  56. return nil, err
  57. }
  58. args = append(session.statement.joinArgs, condArgs...)
  59. sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // for mssql and use limit
  64. qs := strings.Count(sqlStr, "?")
  65. if len(args)*2 == qs {
  66. args = append(args, args...)
  67. }
  68. }
  69. } else {
  70. sqlStr = sqlorArgs[0].(string)
  71. args = sqlorArgs[1:]
  72. }
  73. return session.queryBytes(sqlStr, args...)
  74. }
  75. func value2String(rawValue *reflect.Value) (str string, err error) {
  76. aa := reflect.TypeOf((*rawValue).Interface())
  77. vv := reflect.ValueOf((*rawValue).Interface())
  78. switch aa.Kind() {
  79. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  80. str = strconv.FormatInt(vv.Int(), 10)
  81. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  82. str = strconv.FormatUint(vv.Uint(), 10)
  83. case reflect.Float32, reflect.Float64:
  84. str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
  85. case reflect.String:
  86. str = vv.String()
  87. case reflect.Array, reflect.Slice:
  88. switch aa.Elem().Kind() {
  89. case reflect.Uint8:
  90. data := rawValue.Interface().([]byte)
  91. str = string(data)
  92. if str == "\x00" {
  93. str = "0"
  94. }
  95. default:
  96. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  97. }
  98. // time type
  99. case reflect.Struct:
  100. if aa.ConvertibleTo(core.TimeType) {
  101. str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
  102. } else {
  103. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  104. }
  105. case reflect.Bool:
  106. str = strconv.FormatBool(vv.Bool())
  107. case reflect.Complex128, reflect.Complex64:
  108. str = fmt.Sprintf("%v", vv.Complex())
  109. /* TODO: unsupported types below
  110. case reflect.Map:
  111. case reflect.Ptr:
  112. case reflect.Uintptr:
  113. case reflect.UnsafePointer:
  114. case reflect.Chan, reflect.Func, reflect.Interface:
  115. */
  116. default:
  117. err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
  118. }
  119. return
  120. }
  121. func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
  122. result := make(map[string]string)
  123. scanResultContainers := make([]interface{}, len(fields))
  124. for i := 0; i < len(fields); i++ {
  125. var scanResultContainer interface{}
  126. scanResultContainers[i] = &scanResultContainer
  127. }
  128. if err := rows.Scan(scanResultContainers...); err != nil {
  129. return nil, err
  130. }
  131. for ii, key := range fields {
  132. rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
  133. // if row is null then as empty string
  134. if rawValue.Interface() == nil {
  135. result[key] = ""
  136. continue
  137. }
  138. if data, err := value2String(&rawValue); err == nil {
  139. result[key] = data
  140. } else {
  141. return nil, err
  142. }
  143. }
  144. return result, nil
  145. }
  146. func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
  147. fields, err := rows.Columns()
  148. if err != nil {
  149. return nil, err
  150. }
  151. for rows.Next() {
  152. result, err := row2mapStr(rows, fields)
  153. if err != nil {
  154. return nil, err
  155. }
  156. resultsSlice = append(resultsSlice, result)
  157. }
  158. return resultsSlice, nil
  159. }
  160. // QueryString runs a raw sql and return records as []map[string]string
  161. func (session *Session) QueryString(sqlStr string, args ...interface{}) ([]map[string]string, error) {
  162. if session.isAutoClose {
  163. defer session.Close()
  164. }
  165. rows, err := session.queryRows(sqlStr, args...)
  166. if err != nil {
  167. return nil, err
  168. }
  169. defer rows.Close()
  170. return rows2Strings(rows)
  171. }
  172. func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
  173. resultsMap = make(map[string]interface{}, len(fields))
  174. scanResultContainers := make([]interface{}, len(fields))
  175. for i := 0; i < len(fields); i++ {
  176. var scanResultContainer interface{}
  177. scanResultContainers[i] = &scanResultContainer
  178. }
  179. if err := rows.Scan(scanResultContainers...); err != nil {
  180. return nil, err
  181. }
  182. for ii, key := range fields {
  183. resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface()
  184. }
  185. return
  186. }
  187. func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
  188. fields, err := rows.Columns()
  189. if err != nil {
  190. return nil, err
  191. }
  192. for rows.Next() {
  193. result, err := row2mapInterface(rows, fields)
  194. if err != nil {
  195. return nil, err
  196. }
  197. resultsSlice = append(resultsSlice, result)
  198. }
  199. return resultsSlice, nil
  200. }
  201. // QueryInterface runs a raw sql and return records as []map[string]interface{}
  202. func (session *Session) QueryInterface(sqlStr string, args ...interface{}) ([]map[string]interface{}, error) {
  203. if session.isAutoClose {
  204. defer session.Close()
  205. }
  206. rows, err := session.queryRows(sqlStr, args...)
  207. if err != nil {
  208. return nil, err
  209. }
  210. defer rows.Close()
  211. return rows2Interfaces(rows)
  212. }