2018-03-09 17:55:42 +08:00
|
|
|
|
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
|
|
|
|
// You can obtain one at https://gitee.com/johng/gf.
|
|
|
|
|
|
|
|
|
|
package gdb
|
|
|
|
|
|
|
|
|
|
import (
|
2018-08-08 20:09:52 +08:00
|
|
|
|
"database/sql"
|
2019-02-01 20:45:11 +08:00
|
|
|
|
"gitee.com/johng/gf/g/text/gregex"
|
2018-10-22 11:13:00 +08:00
|
|
|
|
_ "gitee.com/johng/gf/third/github.com/go-sql-driver/mysql"
|
2018-03-09 17:55:42 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 数据库事务对象
|
2018-12-14 18:35:51 +08:00
|
|
|
|
type TX struct {
|
|
|
|
|
db DB
|
2018-10-13 20:29:27 +08:00
|
|
|
|
tx *sql.Tx
|
|
|
|
|
master *sql.DB
|
2018-03-12 11:46:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 事务操作,提交
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Commit() error {
|
2018-12-12 20:01:10 +08:00
|
|
|
|
return tx.tx.Commit()
|
2018-03-12 11:46:12 +08:00
|
|
|
|
}
|
2018-03-09 17:55:42 +08:00
|
|
|
|
|
2018-03-12 11:46:12 +08:00
|
|
|
|
// 事务操作,回滚
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Rollback() error {
|
2018-12-12 20:01:10 +08:00
|
|
|
|
return tx.tx.Rollback()
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-12 15:38:27 +08:00
|
|
|
|
// (事务)数据库sql查询操作,主要执行查询
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doQuery(tx.tx, query, args...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-12 15:38:27 +08:00
|
|
|
|
// (事务)执行一条sql,并返回执行情况,主要用于非查询操作
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Exec(query string, args ...interface{}) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doExec(tx.tx, query, args...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// sql预处理,执行完成后调用返回值sql.Stmt.Exec完成sql操作
|
|
|
|
|
func (tx *TX) Prepare(query string) (*sql.Stmt, error) {
|
|
|
|
|
return tx.db.doPrepare(tx.tx, query)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// 数据库查询,获取查询结果集,以列表结构返回
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) GetAll(query string, args ...interface{}) (Result, error) {
|
2018-03-12 15:12:38 +08:00
|
|
|
|
rows, err := tx.Query(query, args ...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
if err != nil || rows == nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2018-12-15 15:50:39 +08:00
|
|
|
|
defer rows.Close()
|
2019-01-14 22:55:43 +08:00
|
|
|
|
return tx.db.rowsToResult(rows)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// 数据库查询,获取查询结果记录,以关联数组结构返回
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) GetOne(query string, args ...interface{}) (Record, error) {
|
2018-03-12 15:12:38 +08:00
|
|
|
|
list, err := tx.GetAll(query, args ...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2018-05-17 18:22:50 +08:00
|
|
|
|
if len(list) > 0 {
|
|
|
|
|
return list[0], nil
|
|
|
|
|
}
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据库查询,获取查询结果记录,自动映射数据到给定的struct对象中
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) GetStruct(obj interface{}, query string, args ...interface{}) error {
|
2018-05-17 18:22:50 +08:00
|
|
|
|
one, err := tx.GetOne(query, args...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return one.ToStruct(obj)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// 数据库查询,获取查询字段值
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) GetValue(query string, args ...interface{}) (Value, error) {
|
2018-03-12 15:12:38 +08:00
|
|
|
|
one, err := tx.GetOne(query, args ...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
if err != nil {
|
2018-03-12 15:12:38 +08:00
|
|
|
|
return nil, err
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
for _, v := range one {
|
|
|
|
|
return v, nil
|
|
|
|
|
}
|
2018-03-12 15:12:38 +08:00
|
|
|
|
return nil, nil
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-24 10:38:08 +08:00
|
|
|
|
// 数据库查询,获取查询数量
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) GetCount(query string, args ...interface{}) (int, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
if !gregex.IsMatchString(`(?i)SELECT\s+COUNT\(.+\)\s+FROM`, query) {
|
|
|
|
|
query, _ = gregex.ReplaceString(`(?i)(SELECT)\s+(.+)\s+(FROM)`, `$1 COUNT($2) $3`, query)
|
|
|
|
|
}
|
|
|
|
|
value, err := tx.GetValue(query, args ...)
|
2018-04-24 10:38:08 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return value.Int(), nil
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:单条数据写入, 仅仅执行写入操作,如果存在冲突的主键或者唯一索引,那么报错返回
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Insert(table string, data Map) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doInsert(tx.tx, table, data, OPTION_INSERT)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:单条数据写入, 如果数据存在(主键或者唯一索引),那么删除后重新写入一条
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Replace(table string, data Map) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doInsert(tx.tx, table, data, OPTION_REPLACE)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:单条数据写入, 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Save(table string, data Map) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doInsert(tx.tx, table, data, OPTION_SAVE)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:批量数据指定批次量写入
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) BatchInsert(table string, list List, batch int) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doBatchInsert(tx.tx, table, list, batch, OPTION_INSERT)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么删除后重新写入一条
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) BatchReplace(table string, list List, batch int) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doBatchInsert(tx.tx, table, list, batch, OPTION_REPLACE)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) BatchSave(table string, list List, batch int) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doBatchInsert(tx.tx, table, list, batch, OPTION_SAVE)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:数据更新,统一采用sql预处理
|
2018-03-09 17:55:42 +08:00
|
|
|
|
// data参数支持字符串或者关联数组类型,内部会自行做判断处理
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doUpdate(tx.tx, table, data, condition, args ...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-05-17 18:22:50 +08:00
|
|
|
|
// CURD操作:删除数据
|
2018-12-14 18:35:51 +08:00
|
|
|
|
func (tx *TX) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) {
|
2018-12-15 15:50:39 +08:00
|
|
|
|
return tx.db.doDelete(tx.tx, table, condition, args ...)
|
2018-03-09 17:55:42 +08:00
|
|
|
|
}
|
2018-05-17 18:22:50 +08:00
|
|
|
|
|