Ai
1 Star 1 Fork 1

unsafe-rust/sqlx

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
8_sql.go 14.91 KB
一键复制 编辑 原始数据 按行查看 历史
unsafe-rust 提交于 2021-03-28 12:09 +08:00 . update
package sqlx
import (
"database/sql"
"fmt"
"gitee.com/gopher2011/sqlx/reflectx"
"reflect"
)
// Stmt 是 sql.Stmt 的扩展。
type Stmt struct {
*sql.Stmt
unsafe bool
Mapper *reflectx.Mapper
}
// Unsafe 返回一个Stmt版本,当SQL结果中的列在目标结构中没有字段时,它将以静默方式成功扫描。
func (s *Stmt) Unsafe() *Stmt {
return &Stmt{Stmt: s.Stmt, unsafe: true, Mapper: s.Mapper}
}
// qStmt 是一个未公开的包装器,通过实现这些接口并忽略`query`参数,您可以将Stmt用作 IQuery &Execer。
type qStmt struct{ *Stmt }
// Query database/sql包下的原生的 Query()
func (q *qStmt) Query(query string, args ...interface{}) (*sql.Rows, error) {
return q.Stmt.Query(args...)
}
// QueryX *sqlx包下的 QueryX()
func (q *qStmt) QueryX(query string, args ...interface{}) (*Rows, error) {
r, err := q.Stmt.Query(args...)
if err != nil {
return nil, err
}
return &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err
}
// QueryRowX *sqlx包下的 QueryRowX()
func (q *qStmt) QueryRowX(query string, args ...interface{}) *Row {
rows, err := q.Stmt.Query(args...)
return &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}
}
// Exec database/sql 包下的原生的 stmt.Exec()
func (q *qStmt) Exec(query string, args ...interface{}) (sql.Result, error) {
return q.Stmt.Exec(args...)
}
// ExecPanic 原(MustExec) (panic) using this statement.
// 请注意,错误输出的查询部分将为空白,因为Stmt不会公开其查询。
// 任何占位符参数都将替换为提供的args。
func (s *Stmt) ExecPanic(args ...interface{}) sql.Result {
return ExecPanic(&qStmt{s}, "", args...)
}
// QueryRowX using this statement.
// 任何占位符参数都将替换为提供的args。
func (s *Stmt) QueryRowX(args ...interface{}) *Row {
qs := &qStmt{s}
return qs.QueryRowX("", args...)
}
// QueryX using this statement.
// 任何占位符参数都将替换为提供的args。
func (s *Stmt) QueryX(args ...interface{}) (*Rows, error) {
qs := &qStmt{s}
return qs.QueryX("", args...)
}
// Select 查询多行记录,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的args。
func (s *Stmt) Select(pointer interface{}, args ...interface{}) error {
return Select(&qStmt{s}, pointer, "", args...)
}
// Take (原Get) 查询一条记录,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的args。如果结果集为空,则返回错误。
func (s *Stmt) Take(pointer interface{}, args ...interface{}) error {
return Take(&qStmt{s}, pointer, "", args...)
}
// StmtN (原NamedStmt) 是执行命名参数查询的预加载语句。
// 准备如何执行 NamedQuery,但在执行时传入结构体或map。
type StmtN struct {
Stmt *Stmt
Params []string
QueryString string
}
// Unsafe creates an unsafe version of the NamedStmt
func (n *StmtN) Unsafe() *StmtN {
r := &StmtN{Params: n.Params, Stmt: n.Stmt, QueryString: n.QueryString}
r.Stmt.unsafe = true
return r
}
// Close closes the named statement.
func (n *StmtN) Close() error {
return n.Stmt.Close()
}
// Query executes a named statement using the struct argument, returning rows.
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) Query(arg interface{}) (*sql.Rows, error) {
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
if err != nil {
return nil, err
}
return n.Stmt.Query(args...)
}
// QueryRow executes a named statement against the database. Because sqlx cannot
// create a *sql.Row with an error condition pre-set for binding errors, sqlx
// returns a *sqlx.Row instead.
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) QueryRow(arg interface{}) *Row {
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
if err != nil {
return &Row{err: err}
}
return n.Stmt.QueryRowX(args...)
}
// Exec executes a named statement using the struct passed.
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) Exec(arg interface{}) (sql.Result, error) {
args, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)
if err != nil {
return *new(sql.Result), err
}
return n.Stmt.Exec(args...)
}
// ExecPanic (原MustExec) execs a NamedStmt, panicing on error
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) ExecPanic(arg interface{}) sql.Result {
res, err := n.Exec(arg)
if err != nil {
panic(err)
}
return res
}
// QueryX using this NamedStmt
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) QueryX(arg interface{}) (*Rows, error) {
r, err := n.Query(arg)
if err != nil {
return nil, err
}
return &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err
}
// QueryRowX this NamedStmt. Because of limitations with QueryRow, this is
// an alias for QueryRow.
// Any named placeholder parameters are replaced with fields from arg.
func (n *StmtN) QueryRowX(arg interface{}) *Row {
return n.QueryRow(arg)
}
// Select 查询多行记录,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的args。
func (n *StmtN) Select(pointer interface{}, arg interface{}) error {
rows, err := n.QueryX(arg)
if err != nil {
return err
}
// if something happens here, we want to make sure the rows are Closed
defer rows.Close()
return scanAll(rows, pointer, false)
}
// Take (原Get) 查询一条记录,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的args。如果结果集为空,则返回错误。
func (n *StmtN) Take(pointer interface{}, arg interface{}) error {
r := n.QueryRowX(arg)
return r.scanAny(pointer, false)
}
// Conn 是对 sql.Conn 的扩展。
type Conn struct {
*sql.Conn
driverName string
unsafe bool
Mapper *reflectx.Mapper
}
// DB 是 sql.DB 的包装,在打开时跟踪driverName,通常用于使用正确的 bindVars 自动绑定命名查询。
type DB struct {
*sql.DB
driverName string
unsafe bool
Mapper *reflectx.Mapper
}
// NewDB 输入一个 *sql.DB 和 数据库驱动,返回一个 *sqlx.DB实例。
// 这是 sqlx.DB 的构造函数。
// 原始数据库的driverName是命名查询支持所必需的。
func NewDB(db *sql.DB, driverName string) *DB {
return &DB{DB: db, driverName: driverName, Mapper: mapper()}
}
// Open 与sql.Open相同,但返回 *sqlx.DB。
func Open(driverName, dataSourceName string) (*DB, error) {
db, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
return &DB{DB: db, driverName: driverName, Mapper: mapper()}, err
}
// Connect 连接到数据库并通过 ping 进行验证,ping失败则关闭数据库连接,并返回error。
func Connect(driverName, dataSourceName string) (*DB, error) {
db, err := Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
err = db.Ping()
if err != nil {
db.Close()
return nil, err
}
return db, nil
}
// MapperFunc 使用默认的 sqlx.struct 标记和提供的 mapper 函数为此数据库设置一个新的 mapper。
func (db *DB) MapperFunc(mf func(string) string) {
db.Mapper = reflectx.NewMapperFunc("d", mf)
}
// Unsafe 返回一个DB版本,当SQL结果中的列在目标结构中没有字段时,它将以静默方式成功扫描。
// 从此数据库创建的sqlx.Stmt和sqlx.Tx将继承其安全行为。
func (db *DB) Unsafe() *DB {
return &DB{DB: db.DB, driverName: db.driverName, unsafe: true, Mapper: db.Mapper}
}
// BeginX 开启一个事务,(区别于原生Begin) 并返回 *sqlx.Tx 而不是 *sql.Tx。
func (db *DB) BeginX() (*Tx, error) {
tx, err := db.DB.Begin()
if err != nil {
return nil, err
}
return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err
}
// MustBegin starts a transaction, and panics on error. Returns an *sqlx.Tx instead
// of an *sql.Tx.
func (db *DB) BeginPanic() *Tx {
tx, err := db.BeginX()
if err != nil {
panic(err)
}
return tx
}
// MustExec (panic) runs MustExec using this database.
// Any placeholder parameters are replaced with supplied args.
func (db *DB) ExecPanic(query string, args ...interface{}) sql.Result {
return ExecPanic(db, query, args...)
}
// DriverName 返回传递给该数据库的 Open() 函数的driverName。
// (获取当前数据库的驱动名称)
func (db *DB) DriverName() string {
return db.driverName
}
// Rebind 将查询从 Question 转换为数据库驱动程序的 bindVar 类型。
func (db *DB) Rebind(query string) string {
return Rebind(BindType(db.driverName), query)
}
// BindNamed 使用数据库驱动程序的 bindvar 类型绑定查询。
func (db *DB) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
return bindNamedMapper(BindType(db.driverName), query, arg, db.Mapper)
}
// QueryX 查询数据库并返回 *sqlx.Rows。
// 任何占位符参数都将替换为提供的args。
func (db *DB) QueryX(query string, args ...interface{}) (*Rows, error) {
r, err := db.DB.Query(query, args...)
if err != nil {
return nil, err
}
return &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err
}
// QueryRowX 查询数据库并返回 *sqlx.Row。
// 任何占位符参数都将替换为提供的args。
func (db *DB) QueryRowX(query string, args ...interface{}) *Row {
rows, err := db.DB.Query(query, args...)
return &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper}
}
// PrepareX 返回 *sqlx.Stmt 而不是 *sql.Stmt
func (db *DB) PrepareX(query string) (*Stmt, error) {
return PrepareX(db, query)
}
// PrepareNamed 返回一个 *sqlx.NamedStmt,*StmtN 支持命名参数。
func (db *DB) PrepareN(query string) (*StmtN, error) {
return prepareNamed(db, query)
}
// NamedQuery using this DB.
// Any named placeholder parameters are replaced with fields from arg.
func (db *DB) QueryN(query string, arg interface{}) (*Rows, error) {
return NamedQuery(db, query, arg) // 该函数在 6_util_named.go
}
// NamedExec using this DB.
// Any named placeholder parameters are replaced with fields from arg.
func (db *DB) ExecN(query string, arg interface{}) (sql.Result, error) {
return NamedExec(db, query, arg) // 该函数在 6_util_named.go
}
// Select 查询多条数据,并将结果扫描进<pointer>中。参数<pointer>必须是切片(slice)类型。
// <querySql>是查询SQL语句,<args>是查询SQL语句需要的参数。
// 任何占位符参数都将替换为提供的args。
func (db *DB) Select(pointer interface{}, querySql string, args ...interface{}) error {
return Select(db, pointer, querySql, args...)
}
// Take 查询任意一条数据,并将结果扫描进<pointer>中。参数<pointer>可以是 struct/*struct。
// <querySql>是查询SQL语句,<args>是查询SQL语句需要的参数。
// 任何占位符参数都将替换为提供的args。如果结果集为空,则返回错误。
func (db *DB) Take (pointer interface{}, querySql string, args ...interface{}) error {
return Take(db, pointer, querySql, args...)
}
// Tx 是对 sql.Tx 的扩展。
type Tx struct {
*sql.Tx
driverName string
unsafe bool
Mapper *reflectx.Mapper
}
// DriverName 返回开始该事务的数据库使用的 driverName。
func (tx *Tx) DriverName() string {
return tx.driverName
}
// Rebind 事务的bindVar类型的查询。
func (tx *Tx) Rebind(query string) string {
return Rebind(BindType(tx.driverName), query)
}
// BindNamed binds a query within a transaction's bindvar type.
func (tx *Tx) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
return bindNamedMapper(BindType(tx.driverName), query, arg, tx.Mapper)
}
// Unsafe returns a version of Tx which will silently succeed to scan when
// columns in the SQL result have no fields in the destination struct.
func (tx *Tx) Unsafe() *Tx {
return &Tx{Tx: tx.Tx, driverName: tx.driverName, unsafe: true, Mapper: tx.Mapper}
}
// QueryX 区别于 database/sql 包下的原生 Tx.Query()
// 任何占位符参数都将替换为提供的args。
func (tx *Tx) QueryX(query string, args ...interface{}) (*Rows, error) {
r, err := tx.Tx.Query(query, args...)
if err != nil {
return nil, err
}
return &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err
}
// QueryRowX 区别于 database/sql 包下的原生 Tx.QueryRow()
// 任何占位符参数都将替换为提供的args。
func (tx *Tx) QueryRowX(query string, args ...interface{}) *Row {
rows, err := tx.Tx.Query(query, args...)
return &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper}
}
// QueryN (原NamedQuery) 区别于原生的 Tx.Query(),它支持命名参数查询多条记录。
// 任何命名的占位符参数都将替换为arg中的字段。
func (tx *Tx) QueryN(query string, arg interface{}) (*Rows, error) {
return NamedQuery(tx, query, arg)
}
// ExecN (原NamedExec) 区别于原生的 Tx.Query(),它支持命名参数执行SQL语句。
// 任何命名的占位符参数都将替换为arg中的字段。
func (tx *Tx) ExecN(query string, arg interface{}) (sql.Result, error) {
return NamedExec(tx, query, arg)
}
// ExecPanic (原MustExec)区别于原生的 Tx.Exec(),如果执行出错,它内部会 panic。
// 任何占位符参数都将替换为提供的args。
func (tx *Tx) ExecPanic(query string, args ...interface{}) sql.Result {
return ExecPanic(tx, query, args...)
}
// Select 通过事务查询多条数据,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的args。
func (tx *Tx) Select(pointer interface{}, query string, args ...interface{}) error {
return Select(tx, pointer, query, args...)
}
// Take 通过事务查询任意一条数据,并将结果扫描进<pointer>中,参数<pointer>可以是 struct/*struct。
// 任何占位符参数都将替换为提供的参数。如果结果集为空,则返回错误。
func (tx *Tx) Take (pointer interface{}, query string, args ...interface{}) error {
return Take(tx, pointer, query, args...)
}
// PrepareX a statement within a transaction.
func (tx *Tx) PrepareX(query string) (*Stmt, error) {
return PrepareX(tx, query)
}
// PrepareNamed 返回一个 *sqlx.NamedStmt
func (tx *Tx) PrepareN(query string) (*StmtN, error) {
return prepareNamed(tx, query)
}
// StmtX 返回在事务中运行的 prepared语句的版本。提供的stmt可以是 *sql.Stmt 或 *sqlx.Stmt。
func (tx *Tx) StmtX(stmt interface{}) *Stmt {
var s *sql.Stmt
switch v := stmt.(type) {
case Stmt:
s = v.Stmt
case *Stmt:
s = v.Stmt
case *sql.Stmt:
s = v
default:
panic(fmt.Sprintf("non-statement type %v passed to Stmtx", reflect.ValueOf(stmt).Type()))
}
return &Stmt{Stmt: tx.Stmt(s), Mapper: tx.Mapper}
}
// NamedStmt 返回在事务中运行的prepared语句的版本,返回一个 *sqlx.NamedStmt
func (tx *Tx) StmtN(stmt *StmtN) *StmtN {
return &StmtN{
QueryString: stmt.QueryString,
Params: stmt.Params,
Stmt: tx.StmtX(stmt.Stmt),
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/unsafe-rust/sqlx.git
git@gitee.com:unsafe-rust/sqlx.git
unsafe-rust
sqlx
sqlx
master

搜索帮助