Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle https://xorm.io
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.
 
 
 
 
 

181 lines
4.1 KiB

  1. // Copyright 2016 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. "database/sql"
  7. "reflect"
  8. "xorm.io/xorm/core"
  9. )
  10. func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
  11. for _, filter := range session.engine.dialect.Filters() {
  12. *sqlStr = filter.Do(*sqlStr)
  13. }
  14. session.lastSQL = *sqlStr
  15. session.lastSQLArgs = paramStr
  16. }
  17. func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Rows, error) {
  18. defer session.resetStatement()
  19. if session.statement.LastError != nil {
  20. return nil, session.statement.LastError
  21. }
  22. session.queryPreprocess(&sqlStr, args...)
  23. session.lastSQL = sqlStr
  24. session.lastSQLArgs = args
  25. if session.isAutoCommit {
  26. var db *core.DB
  27. if session.sessionType == groupSession {
  28. db = session.engine.engineGroup.Slave().DB()
  29. } else {
  30. db = session.DB()
  31. }
  32. if session.prepareStmt {
  33. // don't clear stmt since session will cache them
  34. stmt, err := session.doPrepare(db, sqlStr)
  35. if err != nil {
  36. return nil, err
  37. }
  38. rows, err := stmt.QueryContext(session.ctx, args...)
  39. if err != nil {
  40. return nil, err
  41. }
  42. return rows, nil
  43. }
  44. rows, err := db.QueryContext(session.ctx, sqlStr, args...)
  45. if err != nil {
  46. return nil, err
  47. }
  48. return rows, nil
  49. }
  50. rows, err := session.tx.QueryContext(session.ctx, sqlStr, args...)
  51. if err != nil {
  52. return nil, err
  53. }
  54. return rows, nil
  55. }
  56. func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row {
  57. return core.NewRow(session.queryRows(sqlStr, args...))
  58. }
  59. func value2Bytes(rawValue *reflect.Value) ([]byte, error) {
  60. str, err := value2String(rawValue)
  61. if err != nil {
  62. return nil, err
  63. }
  64. return []byte(str), nil
  65. }
  66. func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
  67. result := make(map[string][]byte)
  68. scanResultContainers := make([]interface{}, len(fields))
  69. for i := 0; i < len(fields); i++ {
  70. var scanResultContainer interface{}
  71. scanResultContainers[i] = &scanResultContainer
  72. }
  73. if err := rows.Scan(scanResultContainers...); err != nil {
  74. return nil, err
  75. }
  76. for ii, key := range fields {
  77. rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
  78. //if row is null then ignore
  79. if rawValue.Interface() == nil {
  80. result[key] = []byte{}
  81. continue
  82. }
  83. if data, err := value2Bytes(&rawValue); err == nil {
  84. result[key] = data
  85. } else {
  86. return nil, err // !nashtsai! REVIEW, should return err or just error log?
  87. }
  88. }
  89. return result, nil
  90. }
  91. func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
  92. fields, err := rows.Columns()
  93. if err != nil {
  94. return nil, err
  95. }
  96. for rows.Next() {
  97. result, err := row2map(rows, fields)
  98. if err != nil {
  99. return nil, err
  100. }
  101. resultsSlice = append(resultsSlice, result)
  102. }
  103. return resultsSlice, nil
  104. }
  105. func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
  106. rows, err := session.queryRows(sqlStr, args...)
  107. if err != nil {
  108. return nil, err
  109. }
  110. defer rows.Close()
  111. return rows2maps(rows)
  112. }
  113. func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
  114. defer session.resetStatement()
  115. session.queryPreprocess(&sqlStr, args...)
  116. session.lastSQL = sqlStr
  117. session.lastSQLArgs = args
  118. if !session.isAutoCommit {
  119. return session.tx.ExecContext(session.ctx, sqlStr, args...)
  120. }
  121. if session.prepareStmt {
  122. stmt, err := session.doPrepare(session.DB(), sqlStr)
  123. if err != nil {
  124. return nil, err
  125. }
  126. res, err := stmt.ExecContext(session.ctx, args...)
  127. if err != nil {
  128. return nil, err
  129. }
  130. return res, nil
  131. }
  132. return session.DB().ExecContext(session.ctx, sqlStr, args...)
  133. }
  134. // Exec raw sql
  135. func (session *Session) Exec(sqlOrArgs ...interface{}) (sql.Result, error) {
  136. if session.isAutoClose {
  137. defer session.Close()
  138. }
  139. if len(sqlOrArgs) == 0 {
  140. return nil, ErrUnSupportedType
  141. }
  142. sqlStr, args, err := session.statement.ConvertSQLOrArgs(sqlOrArgs...)
  143. if err != nil {
  144. return nil, err
  145. }
  146. return session.exec(sqlStr, args...)
  147. }