You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
7.9 KiB

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