gdb_statement.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gdb
  7. import (
  8. "context"
  9. "database/sql"
  10. )
  11. // Stmt is a prepared statement.
  12. // A Stmt is safe for concurrent use by multiple goroutines.
  13. //
  14. // If a Stmt is prepared on a Tx or Conn, it will be bound to a single
  15. // underlying connection forever. If the Tx or Conn closes, the Stmt will
  16. // become unusable and all operations will return an error.
  17. // If a Stmt is prepared on a DB, it will remain usable for the lifetime of the
  18. // DB. When the Stmt needs to execute on a new underlying connection, it will
  19. // prepare itself on the new connection automatically.
  20. type Stmt struct {
  21. *sql.Stmt
  22. core *Core
  23. link Link
  24. sql string
  25. }
  26. // ExecContext executes a prepared statement with the given arguments and
  27. // returns a Result summarizing the effect of the statement.
  28. func (s *Stmt) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) {
  29. out, err := s.core.db.DoCommit(ctx, DoCommitInput{
  30. Stmt: s.Stmt,
  31. Link: s.link,
  32. Sql: s.sql,
  33. Args: args,
  34. Type: SqlTypeStmtExecContext,
  35. IsTransaction: s.link.IsTransaction(),
  36. })
  37. return out.Result, err
  38. }
  39. // QueryContext executes a prepared query statement with the given arguments
  40. // and returns the query results as a *Rows.
  41. func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) {
  42. out, err := s.core.db.DoCommit(ctx, DoCommitInput{
  43. Stmt: s.Stmt,
  44. Link: s.link,
  45. Sql: s.sql,
  46. Args: args,
  47. Type: SqlTypeStmtQueryContext,
  48. IsTransaction: s.link.IsTransaction(),
  49. })
  50. if err != nil {
  51. return nil, err
  52. }
  53. if out.RawResult != nil {
  54. return out.RawResult.(*sql.Rows), err
  55. }
  56. return nil, nil
  57. }
  58. // QueryRowContext executes a prepared query statement with the given arguments.
  59. // If an error occurs during the execution of the statement, that error will
  60. // be returned by a call to Scan on the returned *Row, which is always non-nil.
  61. // If the query selects no rows, the *Row's Scan will return ErrNoRows.
  62. // Otherwise, the *Row's Scan scans the first selected row and discards
  63. // the rest.
  64. func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row {
  65. out, err := s.core.db.DoCommit(ctx, DoCommitInput{
  66. Stmt: s.Stmt,
  67. Link: s.link,
  68. Sql: s.sql,
  69. Args: args,
  70. Type: SqlTypeStmtQueryContext,
  71. IsTransaction: s.link.IsTransaction(),
  72. })
  73. if err != nil {
  74. panic(err)
  75. }
  76. if out.RawResult != nil {
  77. return out.RawResult.(*sql.Row)
  78. }
  79. return nil
  80. }
  81. // Exec executes a prepared statement with the given arguments and
  82. // returns a Result summarizing the effect of the statement.
  83. func (s *Stmt) Exec(args ...interface{}) (sql.Result, error) {
  84. return s.ExecContext(context.Background(), args...)
  85. }
  86. // Query executes a prepared query statement with the given arguments
  87. // and returns the query results as a *Rows.
  88. func (s *Stmt) Query(args ...interface{}) (*sql.Rows, error) {
  89. return s.QueryContext(context.Background(), args...)
  90. }
  91. // QueryRow executes a prepared query statement with the given arguments.
  92. // If an error occurs during the execution of the statement, that error will
  93. // be returned by a call to Scan on the returned *Row, which is always non-nil.
  94. // If the query selects no rows, the *Row's Scan will return ErrNoRows.
  95. // Otherwise, the *Row's Scan scans the first selected row and discards
  96. // the rest.
  97. //
  98. // Example usage:
  99. //
  100. // var name string
  101. // err := nameByUseridStmt.QueryRow(id).Scan(&name)
  102. func (s *Stmt) QueryRow(args ...interface{}) *sql.Row {
  103. return s.QueryRowContext(context.Background(), args...)
  104. }
  105. // Close closes the statement.
  106. func (s *Stmt) Close() error {
  107. return s.Stmt.Close()
  108. }