github.com/wangyougui/gf/v2@v2.6.5/database/gdb/gdb_statement.go (about)

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