|
|
@ -0,0 +1,463 @@ |
|
|
|
package dbquery |
|
|
|
|
|
|
|
/** |
|
|
|
* 事务操作 |
|
|
|
*/ |
|
|
|
import ( |
|
|
|
"database/sql" |
|
|
|
"errors" |
|
|
|
"log" |
|
|
|
"strconv" |
|
|
|
"strings" |
|
|
|
|
|
|
|
"git.tetele.net/tgo/helper" |
|
|
|
) |
|
|
|
|
|
|
|
type TxQuery struct { |
|
|
|
dbname string |
|
|
|
table string |
|
|
|
alias string |
|
|
|
title string |
|
|
|
where []string |
|
|
|
where_or []string |
|
|
|
join [][]string //[["tablea as a","a.id=b.id","left"]]
|
|
|
|
data []string |
|
|
|
value []interface{} |
|
|
|
orderby string |
|
|
|
page int |
|
|
|
page_size int |
|
|
|
stmt *sql.Stmt |
|
|
|
conn *sql.DB |
|
|
|
tx *sql.Tx |
|
|
|
debug bool |
|
|
|
} |
|
|
|
|
|
|
|
func NewTxQuery(t ...string) *TxQuery { |
|
|
|
|
|
|
|
var conn_type *sql.DB = DB |
|
|
|
|
|
|
|
if len(t) > 0 { |
|
|
|
switch t[0] { |
|
|
|
case "mysql": |
|
|
|
conn_type = DB |
|
|
|
|
|
|
|
case "mssql": //sql server
|
|
|
|
conn_type = MSDB_CONN |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
tx, err := conn_type.Begin() |
|
|
|
if err != nil { |
|
|
|
log.Println("start tx begin error", err) |
|
|
|
} |
|
|
|
|
|
|
|
return &TxQuery{ |
|
|
|
conn: conn_type, |
|
|
|
tx: tx, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func (this *TxQuery) Conn(conn *sql.DB) *TxQuery { |
|
|
|
this.conn = conn |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Db(dbname string) *TxQuery { |
|
|
|
this.dbname = dbname |
|
|
|
return this |
|
|
|
} |
|
|
|
|
|
|
|
func (this *TxQuery) Table(tablename string) *TxQuery { |
|
|
|
this.table = tablename |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Alias(tablename string) *TxQuery { |
|
|
|
this.alias = tablename |
|
|
|
return this |
|
|
|
} |
|
|
|
|
|
|
|
func (this *TxQuery) Title(title string) *TxQuery { |
|
|
|
this.title = title |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Page(page int) *TxQuery { |
|
|
|
this.page = page |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) PageSize(page_num int) *TxQuery { |
|
|
|
this.page_size = page_num |
|
|
|
return this |
|
|
|
} |
|
|
|
|
|
|
|
func (this *TxQuery) Orderby(orderby string) *TxQuery { |
|
|
|
this.orderby = orderby |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Where(where string) *TxQuery { |
|
|
|
this.where = append(this.where, where) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Wheres(wheres []string) *TxQuery { |
|
|
|
if len(wheres) > 0 { |
|
|
|
this.where = append(this.where, wheres...) |
|
|
|
} |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) WhereOr(where string) *TxQuery { |
|
|
|
this.where_or = append(this.where_or, where) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Value(value interface{}) *TxQuery { |
|
|
|
this.value = append(this.value, value) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Values(values []interface{}) *TxQuery { |
|
|
|
this.value = append(this.value, values...) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Join(join []string) *TxQuery { |
|
|
|
this.join = append(this.join, join) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Data(data string) *TxQuery { |
|
|
|
this.data = append(this.data, data) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Datas(datas []string) *TxQuery { |
|
|
|
this.data = append(this.data, datas...) |
|
|
|
return this |
|
|
|
} |
|
|
|
func (this *TxQuery) Debug(debug bool) *TxQuery { |
|
|
|
this.debug = debug |
|
|
|
return this |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* 清理上次查询 |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Clean() *TxQuery { |
|
|
|
this.title = "" |
|
|
|
this.where = this.where[0:0] |
|
|
|
this.where_or = this.where_or[0:0] |
|
|
|
this.join = this.join[0:0] |
|
|
|
this.data = this.data[0:0] |
|
|
|
this.value = this.value[0:0] |
|
|
|
this.orderby = "" |
|
|
|
this.page = 0 |
|
|
|
this.page_size = 0 |
|
|
|
return this |
|
|
|
} |
|
|
|
|
|
|
|
// 拼查询sql
|
|
|
|
func (this *TxQuery) QueryStmt() error { |
|
|
|
|
|
|
|
if this.dbname == "" && this.table == "" { |
|
|
|
return errors.New("参数错误,没有数据表") |
|
|
|
} |
|
|
|
|
|
|
|
table := getTableName(this.dbname, this.table) |
|
|
|
|
|
|
|
var sql, title string |
|
|
|
|
|
|
|
if this.title != "" { |
|
|
|
title = this.title |
|
|
|
} else { |
|
|
|
title = "*" |
|
|
|
} |
|
|
|
sql = helper.StringJoin("select ", title) |
|
|
|
|
|
|
|
if this.alias != "" { |
|
|
|
table = helper.StringJoin(table, " as ", this.alias) |
|
|
|
} |
|
|
|
|
|
|
|
sql = helper.StringJoin(sql, " from ", table) |
|
|
|
|
|
|
|
if len(this.join) > 0 { |
|
|
|
for _, joinitem := range this.join { |
|
|
|
if len(joinitem) < 2 { |
|
|
|
continue |
|
|
|
} |
|
|
|
if len(joinitem) == 3 { |
|
|
|
sql = helper.StringJoin(sql, " ", joinitem[2], " join ", getTableName(this.dbname, joinitem[0]), " on ", joinitem[1]) |
|
|
|
} else { //默认左连接
|
|
|
|
sql = helper.StringJoin(sql, " left join ", getTableName(this.dbname, joinitem[0]), " on ", joinitem[1]) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if len(this.where) > 0 || len(this.where_or) > 0 { |
|
|
|
sql = helper.StringJoin(sql, " where ") |
|
|
|
} |
|
|
|
if len(this.where) > 0 { |
|
|
|
sql = helper.StringJoin(sql, " (", strings.Join(this.where, " and "), " ) ") |
|
|
|
} |
|
|
|
if len(this.where_or) > 0 { |
|
|
|
if len(this.where) > 0 { |
|
|
|
sql = helper.StringJoin(sql, " or ", strings.Join(this.where_or, " or ")) |
|
|
|
} else { |
|
|
|
sql = helper.StringJoin(sql, strings.Join(this.where_or, " or ")) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if this.orderby != "" { |
|
|
|
sql = helper.StringJoin(sql, " order by ", this.orderby) |
|
|
|
} |
|
|
|
|
|
|
|
if this.page > 0 || this.page_size > 0 { |
|
|
|
|
|
|
|
if this.page < 1 { |
|
|
|
this.page = 1 |
|
|
|
} |
|
|
|
if this.page_size < 1 { |
|
|
|
this.page_size = 10 |
|
|
|
} |
|
|
|
from := strconv.Itoa((this.page - 1) * this.page_size) |
|
|
|
offset := strconv.Itoa(this.page_size) |
|
|
|
if from != "" && offset != "" { |
|
|
|
sql = helper.StringJoin(sql, " limit ", from, " , ", offset) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if this.debug { |
|
|
|
log.Println("query sql:", sql, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
condition_len := 0 //所有条件数
|
|
|
|
for _, ch2 := range sql { |
|
|
|
if string(ch2) == "?" { |
|
|
|
condition_len++ |
|
|
|
} |
|
|
|
} |
|
|
|
if condition_len != len(this.value) { |
|
|
|
return errors.New("参数错误,条件值错误") |
|
|
|
} |
|
|
|
|
|
|
|
stmt, err = this.tx.Prepare(sql + " FOR UPDATE") |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
this.stmt = stmt |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// 拼更新sql
|
|
|
|
func (this *TxQuery) UpdateStmt() error { |
|
|
|
|
|
|
|
if this.dbname == "" && this.table == "" { |
|
|
|
return errors.New("参数错误,没有数据表") |
|
|
|
} |
|
|
|
if len(this.where) < 1 { |
|
|
|
return errors.New("参数错误,缺少条件") |
|
|
|
} |
|
|
|
|
|
|
|
dbName := getTableName(this.dbname, this.table) |
|
|
|
|
|
|
|
var sql string |
|
|
|
|
|
|
|
sql = helper.StringJoin("update ", dbName, " set ", strings.Join(this.data, " , ")) |
|
|
|
|
|
|
|
sql = helper.StringJoin(sql, " where ", strings.Join(this.where, " and ")) |
|
|
|
|
|
|
|
if this.debug { |
|
|
|
log.Println("update sql:", sql, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
condition_len := 0 //所有条件数
|
|
|
|
|
|
|
|
for _, ch2 := range sql { |
|
|
|
if string(ch2) == "?" { |
|
|
|
condition_len++ |
|
|
|
} |
|
|
|
} |
|
|
|
if condition_len != len(this.value) { |
|
|
|
return errors.New("参数错误,条件值错误") |
|
|
|
} |
|
|
|
|
|
|
|
stmt, err = this.tx.Prepare(sql) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
this.stmt = stmt |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// 拼插入sql
|
|
|
|
func (this *TxQuery) CreateStmt() error { |
|
|
|
|
|
|
|
if this.dbname == "" && this.table == "" { |
|
|
|
return errors.New("参数错误,没有数据表") |
|
|
|
} |
|
|
|
|
|
|
|
dbName := getTableName(this.dbname, this.table) |
|
|
|
|
|
|
|
var sql string |
|
|
|
|
|
|
|
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , ")) |
|
|
|
|
|
|
|
if this.debug { |
|
|
|
log.Println("insert sql:", sql, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
condition_len := 0 //所有条件数
|
|
|
|
|
|
|
|
for _, ch2 := range sql { |
|
|
|
if string(ch2) == "?" { |
|
|
|
condition_len++ |
|
|
|
} |
|
|
|
} |
|
|
|
if condition_len != len(this.value) { |
|
|
|
return errors.New("参数错误,条件值错误") |
|
|
|
} |
|
|
|
|
|
|
|
stmt, err = this.tx.Prepare(sql) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
this.stmt = stmt |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// 拼删除sql
|
|
|
|
func (this *TxQuery) DeleteStmt() error { |
|
|
|
|
|
|
|
if this.dbname == "" && this.table == "" { |
|
|
|
return errors.New("参数错误,没有数据表") |
|
|
|
} |
|
|
|
if len(this.where) < 1 { |
|
|
|
return errors.New("参数错误,缺少条件") |
|
|
|
} |
|
|
|
|
|
|
|
dbName := getTableName(this.dbname, this.table) |
|
|
|
|
|
|
|
var sql string |
|
|
|
|
|
|
|
sql = helper.StringJoin("delete from ", dbName, " where ", strings.Join(this.where, " and ")) |
|
|
|
|
|
|
|
if this.page_size > 0 { |
|
|
|
sql = helper.StringJoin(sql, " limit ", strconv.Itoa(this.page_size)) |
|
|
|
} |
|
|
|
|
|
|
|
if this.debug { |
|
|
|
log.Println("delete sql:", sql, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
condition_len := 0 //所有条件数
|
|
|
|
|
|
|
|
for _, ch2 := range sql { |
|
|
|
if string(ch2) == "?" { |
|
|
|
condition_len++ |
|
|
|
} |
|
|
|
} |
|
|
|
if condition_len != len(this.value) { |
|
|
|
return errors.New("参数错误,条件值错误") |
|
|
|
} |
|
|
|
|
|
|
|
stmt, err = this.tx.Prepare(sql) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
this.stmt = stmt |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行查询列表 |
|
|
|
* return list error |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Select() ([]map[string]string, error) { |
|
|
|
|
|
|
|
err := this.QueryStmt() |
|
|
|
if err != nil { |
|
|
|
return []map[string]string{}, err |
|
|
|
} |
|
|
|
|
|
|
|
if this.stmt == nil { |
|
|
|
return []map[string]string{}, errors.New("缺少必要参数") |
|
|
|
} |
|
|
|
|
|
|
|
return StmtForQueryList(this.stmt, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行查询一条数据 |
|
|
|
* return row error |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Find() (map[string]string, error) { |
|
|
|
|
|
|
|
err := this.QueryStmt() |
|
|
|
if err != nil { |
|
|
|
return map[string]string{}, err |
|
|
|
} |
|
|
|
|
|
|
|
if this.stmt == nil { |
|
|
|
return nil, errors.New("缺少必要参数") |
|
|
|
} |
|
|
|
return StmtForQueryRow(this.stmt, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行更新 |
|
|
|
* return is_updated error |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Update() (int64, error) { |
|
|
|
|
|
|
|
err := this.UpdateStmt() |
|
|
|
if err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
|
|
|
|
return StmtForUpdateExec(this.stmt, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行删除 |
|
|
|
* return is_delete error |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Delete() (int64, error) { |
|
|
|
|
|
|
|
err := this.DeleteStmt() |
|
|
|
if err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
|
|
|
|
return StmtForUpdateExec(this.stmt, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行写入 |
|
|
|
* return is_insert error |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Create() (int64, error) { |
|
|
|
|
|
|
|
err := this.CreateStmt() |
|
|
|
if err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
|
|
|
|
return StmtForInsertExec(this.stmt, this.value) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 提交 |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Commit() error { |
|
|
|
return this.tx.Commit() |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 回滚 |
|
|
|
*/ |
|
|
|
func (this *TxQuery) Rollback() error { |
|
|
|
return this.tx.Rollback() |
|
|
|
} |