21 Commits

8 changed files with 821 additions and 127 deletions
Unified View
  1. +151
    -18
      chain.go
  2. +42
    -1
      conn.go
  3. +189
    -48
      db.go
  4. +3
    -1
      go.mod
  5. +109
    -3
      go.sum
  6. +69
    -11
      prepare.go
  7. +91
    -30
      transaction.go
  8. +167
    -15
      transaction_chain.go

+ 151
- 18
chain.go View File

@ -3,6 +3,7 @@ package dbquery
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"github.com/jmoiron/sqlx"
"log" "log"
"strconv" "strconv"
"strings" "strings"
@ -34,6 +35,7 @@ type Query struct {
conn *sql.DB conn *sql.DB
debug bool debug bool
dbtype string dbtype string
with [][]string //[[临时表的sql语句,临时表的名称]]
} }
func NewQuery(t ...string) *Query { func NewQuery(t ...string) *Query {
@ -67,6 +69,9 @@ func (this *Query) Conn(conn *sql.DB) *Query {
} }
func (this *Query) Db(dbname string) *Query { func (this *Query) Db(dbname string) *Query {
this.dbname = dbname this.dbname = dbname
if DB_PROVIDER == "PgsqlDb" {
this.dbname = ""
}
return this return this
} }
@ -103,6 +108,14 @@ func (this *Query) Groupby(groupby string) *Query {
this.groupby = groupby this.groupby = groupby
return this return this
} }
func (this *Query) With(with []string) *Query {
this.with = append(this.with, with)
return this
}
func (this *Query) Withs(withs [][]string) *Query {
this.with = append(this.with, withs...)
return this
}
func (this *Query) Where(where string) *Query { func (this *Query) Where(where string) *Query {
this.where = append(this.where, where) this.where = append(this.where, where)
return this return this
@ -145,6 +158,27 @@ func (this *Query) Join(join []string) *Query {
this.join = append(this.join, join) this.join = append(this.join, join)
return this return this
} }
/**
* 左连接
* 2023/08/10
* gz
*/
func (this *Query) LeftJoin(table_name string, condition string) *Query {
this.join = append(this.join, []string{table_name, condition, "left"})
return this
}
/**
* 右连接
* 2023/08/10
* gz
*/
func (this *Query) RightJoin(table_name string, condition string) *Query {
this.join = append(this.join, []string{table_name, condition, "right"})
return this
}
func (this *Query) Data(data string) *Query { func (this *Query) Data(data string) *Query {
this.data = append(this.data, data) this.data = append(this.data, data)
return this return this
@ -176,6 +210,8 @@ func (this *Query) Clean() *Query {
this.save_data = this.save_data[0:0] this.save_data = this.save_data[0:0]
this.upd_field = this.upd_field[0:0] this.upd_field = this.upd_field[0:0]
this.having = "" this.having = ""
this.alias = ""
this.with = this.with[0:0]
return this return this
} }
@ -193,6 +229,10 @@ func (this *Query) GetTableInfo(table string) (map[string]interface{}, error) {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmtSql, err := this.conn.Prepare(sql) stmtSql, err := this.conn.Prepare(sql)
if err != nil { if err != nil {
return nil, err return nil, err
@ -245,13 +285,41 @@ func (this *Query) GetTableInfo(table string) (map[string]interface{}, error) {
}, nil }, nil
} }
// 返回表名
func (this *Query) GetTableName(table string) string {
return getTableName(this.dbname, table)
}
// 构造子查询 // 构造子查询
func (this *Query) BuildSelectSql() (map[string]interface{}, error) { func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
if this.dbname == "" && this.table == "" { if this.dbname == "" && this.table == "" {
return nil, errors.New("参数错误,没有数据表") return nil, errors.New("参数错误,没有数据表")
} }
var table = "" var table = ""
if strings.Contains(this.table, "select ") {
withSql := ""
if len(this.with) > 0 {
var builder strings.Builder
builder.WriteString("WITH ")
boo := false
for k, v := range this.with {
if len(v) < 2 {
continue
}
if k != 0 {
builder.WriteString(", ")
}
builder.WriteString(v[1])
builder.WriteString(" as (")
builder.WriteString(v[0])
builder.WriteString(")")
boo = true
}
if boo {
builder.WriteString(" ")
withSql = builder.String()
}
}
if withSql != "" || strings.Contains(this.table, "select ") || strings.HasPrefix(this.table, "(") {
table = this.table table = this.table
} else { } else {
table = getTableName(this.dbname, this.table, this.dbtype) table = getTableName(this.dbname, this.table, this.dbtype)
@ -269,15 +337,15 @@ func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
if this.dbtype == "mssql" { if this.dbtype == "mssql" {
if this.page_size > 0 { if this.page_size > 0 {
sql = helper.StringJoin("select top ", helper.ToStr(this.page_size), " ")
sql = helper.StringJoin(withSql, "select top ", helper.ToStr(this.page_size), " ")
} else { } else {
sql = "select "
sql = helper.StringJoin(withSql, "select ")
} }
} else { } else {
if DB_PROVIDER == "TencentDB" { if DB_PROVIDER == "TencentDB" {
sql = "/*slave*/ select "
sql = helper.StringJoin("/*slave*/ ", withSql, " select ")
} else { } else {
sql = "select "
sql = helper.StringJoin(withSql, "select ")
} }
} }
@ -290,15 +358,31 @@ func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
sql = helper.StringJoin(sql, " from ", table) sql = helper.StringJoin(sql, " from ", table)
if len(this.join) > 0 { if len(this.join) > 0 {
var builder strings.Builder
builder.WriteString(sql)
boo := false
for _, joinitem := range this.join { for _, joinitem := range this.join {
if len(joinitem) < 2 { if len(joinitem) < 2 {
continue continue
} }
if len(joinitem) == 3 {
sql = helper.StringJoin(sql, " ", joinitem[2], " join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1])
} else { //默认左连接
sql = helper.StringJoin(sql, " left join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1])
builder.WriteString(" ")
if len(joinitem) >= 3 {
builder.WriteString(joinitem[2])
} else {
builder.WriteString("left")
}
builder.WriteString(" join ")
if withSql != "" || strings.Contains(joinitem[0], "select ") || strings.HasPrefix(joinitem[0], "(") {
builder.WriteString(joinitem[0])
} else {
builder.WriteString(getTableName(this.dbname, joinitem[0]))
} }
builder.WriteString(" on ")
builder.WriteString(joinitem[1])
boo = true
}
if boo {
sql = builder.String()
} }
} }
if len(this.where) > 0 || len(this.where_or) > 0 { if len(this.where) > 0 || len(this.where_or) > 0 {
@ -337,7 +421,11 @@ func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
from := strconv.Itoa((this.page - 1) * this.page_size) from := strconv.Itoa((this.page - 1) * this.page_size)
offset := strconv.Itoa(this.page_size) offset := strconv.Itoa(this.page_size)
if from != "" && offset != "" { if from != "" && offset != "" {
sql = helper.StringJoin(sql, " limit ", from, " , ", offset)
if DB_PROVIDER == "PgsqlDb" {
sql = helper.StringJoin(sql, " limit ", offset, " OFFSET ", from)
} else {
sql = helper.StringJoin(sql, " limit ", from, " , ", offset)
}
} }
} }
if this.debug { if this.debug {
@ -352,6 +440,10 @@ func (this *Query) BuildSelectSql() (map[string]interface{}, error) {
if condition_len != len(this.value) { if condition_len != len(this.value) {
return nil, errors.New("参数错误,条件值错误") return nil, errors.New("参数错误,条件值错误")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
return map[string]interface{}{ return map[string]interface{}{
"sql": sql, "sql": sql,
"value": this.value, "value": this.value,
@ -423,7 +515,10 @@ func (this *Query) UpdateStmt() error {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.conn.Prepare(sql) stmt, err = this.conn.Prepare(sql)
if err != nil { if err != nil {
@ -527,6 +622,9 @@ func (this *Query) UpdateAllStmt() error {
if len(valSql) > 1 { if len(valSql) > 1 {
setText = " value " setText = " value "
} }
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
}
sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","), " ON DUPLICATE KEY UPDATE ", strings.Join(updSql, " , ")) sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","), " ON DUPLICATE KEY UPDATE ", strings.Join(updSql, " , "))
if this.debug { if this.debug {
@ -545,7 +643,10 @@ func (this *Query) UpdateAllStmt() error {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.conn.Prepare(sql) stmt, err = this.conn.Prepare(sql)
if err != nil { if err != nil {
@ -616,6 +717,9 @@ func (this *Query) CreateAllStmt() error {
if len(valSql) > 1 { if len(valSql) > 1 {
setText = " value " setText = " value "
} }
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
}
sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ",")) sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","))
if this.debug { if this.debug {
@ -634,7 +738,11 @@ func (this *Query) CreateAllStmt() error {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
sql = helper.StringJoin(sql, " RETURNING id")
}
stmt, err = this.conn.Prepare(sql) stmt, err = this.conn.Prepare(sql)
if err != nil { if err != nil {
@ -656,8 +764,27 @@ func (this *Query) CreateStmt() error {
dbName := getTableName(this.dbname, this.table, this.dbtype) dbName := getTableName(this.dbname, this.table, this.dbtype)
var sql string var sql string
if DB_PROVIDER == "PgsqlDb" {
insert_data := []string{}
value_data := []string{}
for _, rv := range this.data {
dv := strings.Split(rv, "=")
if len(dv) < 2 {
return errors.New("参数错误,条件值错误,=号不存在")
}
if strings.Contains(rv, "?") {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, "?")
} else {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, dv[1])
}
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
}
sql = helper.StringJoin("insert into ", dbName, " ("+strings.Join(insert_data, " , ")+")", " VALUES ", "("+strings.Join(value_data, " , ")+")", " RETURNING id")
} else {
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
}
if this.debug { if this.debug {
log.Println("insert sql:", sql, this.value) log.Println("insert sql:", sql, this.value)
@ -676,7 +803,10 @@ func (this *Query) CreateStmt() error {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.conn.Prepare(sql) stmt, err = this.conn.Prepare(sql)
if err != nil { if err != nil {
@ -725,7 +855,10 @@ func (this *Query) DeleteStmt() error {
if this.conn == nil { if this.conn == nil {
this.conn = DB this.conn = DB
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.conn.Prepare(sql) stmt, err = this.conn.Prepare(sql)
if err != nil { if err != nil {
@ -743,7 +876,7 @@ func (this *Query) DeleteStmt() error {
*/ */
func (this *Query) Select() ([]map[string]string, error) { func (this *Query) Select() ([]map[string]string, error) {
_, rows, err := FetchRows(this.dbname, this.table, this.alias, this.title, this.join,
_, rows, err := FetchRows(this.dbname, this.table, this.alias, this.title, this.with, this.join,
this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.page, this.page_size, this.debug) this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.page, this.page_size, this.debug)
return rows, err return rows, err
@ -774,7 +907,7 @@ func (this *Query) List() ([]map[string]string, error) {
*/ */
func (this *Query) Find() (map[string]string, error) { func (this *Query) Find() (map[string]string, error) {
_, row, err := GetRow(this.dbname, this.table, this.alias, this.title, this.join,
_, row, err := GetRow(this.dbname, this.table, this.alias, this.title, this.with, this.join,
this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.debug) this.where, this.where_or, this.value, this.orderby, this.groupby, this.having, this.debug)
return row, err return row, err


+ 42
- 1
conn.go View File

@ -10,7 +10,9 @@ import (
"git.tetele.net/tgo/helper" "git.tetele.net/tgo/helper"
_ "gitee.com/opengauss/openGauss-connector-go-pq" // 高斯驱动(推荐)或 "github.com/lib/pq"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
//_ "github.com/lib/pq" // 关键驱动导入
) )
var DB *sql.DB var DB *sql.DB
@ -106,7 +108,9 @@ func CloseSlaverConn() error {
func getTableName(dbName, table string, dbtype ...string) string { func getTableName(dbName, table string, dbtype ...string) string {
var db_type string = "mysql" var db_type string = "mysql"
if DB_PROVIDER == "PgsqlDb" {
dbName = ""
}
if len(dbtype) > 0 { if len(dbtype) > 0 {
if dbtype[0] != "" { if dbtype[0] != "" {
db_type = dbtype[0] db_type = dbtype[0]
@ -151,3 +155,40 @@ func GetDbTableName(dbName, table string) string {
func judg() []string { func judg() []string {
return []string{"=", ">", "<", "!=", "<=", ">="} return []string{"=", ">", "<", "!=", "<=", ">="}
} }
func PgConnect(DBHOST, DBUSER, DBPWD, DBNAME, DBPORT string, conns ...int) error {
DB_PROVIDER = "PgsqlDb"
log.Println("pg database connectting...")
var dbConnErr error
if DBHOST != "" && DBUSER != "" && DBPWD != "" && DBPORT != "" { //&& DBNAME != ""
dsn := "host=" + DBHOST + " port=" + DBPORT + " user=" + DBUSER + " password=" + DBPWD + " dbname=" + DBNAME + " sslmode=disable search_path=public"
log.Println("database dsn", dsn)
for i := 0; i < 10; i++ {
DB, dbConnErr = sql.Open("opengauss", dsn)
if dbConnErr != nil {
log.Println("ERROR", "can not connect to pg Database, ", dbConnErr)
time.Sleep(time.Second * 5)
} else {
if len(conns) > 0 {
DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制
} else {
DB.SetMaxOpenConns(200) //默认值为0表示不限制
}
if len(conns) > 1 {
DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数
} else {
DB.SetMaxIdleConns(50)
}
DB.Ping()
log.Println("pg database connected")
DB.SetConnMaxLifetime(time.Minute * 2)
break
}
}
} else {
return errors.New("db connection params errors")
}
return dbConnErr
}

+ 189
- 48
db.go View File

@ -2,6 +2,7 @@ package dbquery
import ( import (
"database/sql" "database/sql"
"github.com/jmoiron/sqlx"
"log" "log"
"strconv" "strconv"
@ -44,16 +45,34 @@ func Insert(dbName, table string, data map[string]string) (int64, error) {
valueList[i] = value valueList[i] = value
i++ i++
} }
result, err := DB.Exec("insert into "+dbName+" ("+strings.Join(keyList, ",")+") value("+strings.Join(keyStr, ",")+")", valueList...)
if err != nil {
log.Println("ERROR|插入", dbName, "数据失败,", err)
return insertId, err
var Sql string
Sql = "insert into " + dbName + " (" + strings.Join(keyList, ",") + ") values (" + strings.Join(keyStr, ",") + ")"
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
Sql = helper.StringJoin(Sql, " RETURNING id")
stmt, err = DB.Prepare(Sql)
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
row := stmt.QueryRow(valueList...)
var id int64
err = row.Scan(&id) // 扫描 RETURNING 返回的 ID
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
return id, nil
} else { } else {
insertId, _ = result.LastInsertId()
time.Sleep(time.Second * 2)
return insertId, nil
result, err := DB.Exec(Sql, valueList...)
if err != nil {
log.Println("ERROR|插入", dbName, "数据失败,", err)
return insertId, err
} else {
insertId, _ = result.LastInsertId()
time.Sleep(time.Second * 2)
return insertId, nil
}
} }
} }
@ -67,7 +86,6 @@ func Update(dbName, table string, data map[string]string, where map[string]strin
if dbName == "" && table == "" { if dbName == "" && table == "" {
return rowsAffected, errors.New("没有数据表") return rowsAffected, errors.New("没有数据表")
} }
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
@ -109,7 +127,13 @@ func Update(dbName, table string, data map[string]string, where map[string]strin
log.Println("ERROR|修改数据表", dbName, "时条件中有空数据,条件:", where, "数据:", data) log.Println("ERROR|修改数据表", dbName, "时条件中有空数据,条件:", where, "数据:", data)
return rowsAffected, errors.New("条件中有空数据") return rowsAffected, errors.New("条件中有空数据")
} }
result, err := DB.Exec("update "+dbName+" set "+strings.Join(keyList, " , ")+" where "+strings.Join(whereStr, " and "), valueList...)
var Sql string
Sql = "update " + dbName + " set " + strings.Join(keyList, " , ") + " where " + strings.Join(whereStr, " and ")
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
result, err := DB.Exec(Sql, valueList...)
if err != nil { if err != nil {
log.Println("ERROR|修改", dbName, "数据失败,", err) log.Println("ERROR|修改", dbName, "数据失败,", err)
@ -131,7 +155,6 @@ func Delete(dbName, table string, data map[string]string, del_count ...string) (
if dbName == "" && table == "" { if dbName == "" && table == "" {
return count, errors.New("没有数据表") return count, errors.New("没有数据表")
} }
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
@ -167,7 +190,13 @@ func Delete(dbName, table string, data map[string]string, del_count ...string) (
limitStr = " limit " + del_count[0] limitStr = " limit " + del_count[0]
} }
result, err := DB.Exec("delete from "+dbName+" where "+strings.Join(keyList, " and ")+limitStr, valueList...)
var Sql string
Sql = "delete from " + dbName + " where " + strings.Join(keyList, " and ") + limitStr
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
result, err := DB.Exec(Sql, valueList...)
if err != nil { if err != nil {
log.Println("ERROR|删除", dbName, "数据失败,", err) log.Println("ERROR|删除", dbName, "数据失败,", err)
@ -191,7 +220,6 @@ func GetData(dbName, table string, title string, where map[string]string, limit
if dbName == "" && table == "" { if dbName == "" && table == "" {
return count, info, errors.New("没有数据表") return count, info, errors.New("没有数据表")
} }
dbName = getTableName(dbName, table) dbName = getTableName(dbName, table)
if len(title) < 1 { if len(title) < 1 {
@ -210,7 +238,11 @@ func GetData(dbName, table string, title string, where map[string]string, limit
if _, ok := limit["from"]; ok { if _, ok := limit["from"]; ok {
from = limit["from"] from = limit["from"]
} }
limitStr += " limit " + from + ",1"
if DB_PROVIDER == "PgsqlDb" {
limitStr += " limit 1 OFFSET " + from
} else {
limitStr += " limit " + from + ",1"
}
} else { } else {
limitStr = " limit 1" limitStr = " limit 1"
@ -241,8 +273,13 @@ func GetData(dbName, table string, title string, where map[string]string, limit
var err error var err error
var queryNum int = 0 var queryNum int = 0
for queryNum < 3 { //如发生错误,继续查询3次,防止数据库连接断开问题 for queryNum < 3 { //如发生错误,继续查询3次,防止数据库连接断开问题
rows, err = DB.Query("SELECT "+title+" FROM "+dbName+" where "+strings.Join(keyList, " and ")+" "+limitStr, valueList...)
var Sql string
Sql = "SELECT " + title + " FROM " + dbName + " where " + strings.Join(keyList, " and ") + " " + limitStr
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
rows, err = DB.Query(Sql, valueList...)
if err == nil { if err == nil {
break break
@ -295,16 +332,38 @@ func GetData(dbName, table string, title string, where map[string]string, limit
* @param dbName 数据表名 * @param dbName 数据表名
* @param title 查询字段名 * @param title 查询字段名
*/ */
func GetRow(dbName, table_name, alias string, titles string, join [][]string, where, where_or []string, valueList []interface{}, orderby, groupby, having string, debug bool) (int, map[string]string, error) {
func GetRow(dbName, table_name, alias string, titles string, with, join [][]string, where, where_or []string, valueList []interface{}, orderby, groupby, having string, debug bool) (int, map[string]string, error) {
var count int = 0 var count int = 0
info := make(map[string]string) info := make(map[string]string)
if dbName == "" && table_name == "" { if dbName == "" && table_name == "" {
return count, info, errors.New("没有数据表") return count, info, errors.New("没有数据表")
} }
table := "" table := ""
if strings.Contains(table_name, "select ") {
withSql := ""
if len(with) > 0 {
var builder strings.Builder
builder.WriteString("WITH ")
boo := false
for k, v := range with {
if len(v) < 2 {
continue
}
if k != 0 {
builder.WriteString(", ")
}
builder.WriteString(v[1])
builder.WriteString(" as (")
builder.WriteString(v[0])
builder.WriteString(")")
boo = true
}
if boo {
builder.WriteString(" ")
withSql = builder.String()
}
}
if withSql != "" || strings.Contains(table_name, "select ") || strings.HasPrefix(table, "(") {
table = table_name table = table_name
} else { } else {
table = getTableName(dbName, table_name) table = getTableName(dbName, table_name)
@ -316,10 +375,11 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
} else { } else {
title = "*" title = "*"
} }
if DB_PROVIDER == "TencentDB" { if DB_PROVIDER == "TencentDB" {
sql_str = helper.StringJoin("/*slave*/ select ", title)
sql_str = helper.StringJoin("/*slave*/ ", withSql, " select ", title)
} else { } else {
sql_str = helper.StringJoin("select ", title)
sql_str = helper.StringJoin(withSql, "select ", title)
} }
if alias != "" { if alias != "" {
table = helper.StringJoin(table, " as ", alias) table = helper.StringJoin(table, " as ", alias)
@ -328,17 +388,31 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
sql_str = helper.StringJoin(sql_str, " from ", table) sql_str = helper.StringJoin(sql_str, " from ", table)
if len(join) > 0 { if len(join) > 0 {
var builder strings.Builder
builder.WriteString(sql_str)
boo := false
for _, joinitem := range join { for _, joinitem := range join {
if len(joinitem) < 2 { if len(joinitem) < 2 {
continue continue
} }
if len(joinitem) == 4 {
sql_str = helper.StringJoin(sql_str, " ", joinitem[2], " join ", joinitem[0], " on ", joinitem[1])
} else if len(joinitem) == 3 {
sql_str = helper.StringJoin(sql_str, " ", joinitem[2], " join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1])
} else { //默认左连接
sql_str = helper.StringJoin(sql_str, " left join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1])
builder.WriteString(" ")
if len(joinitem) >= 3 {
builder.WriteString(joinitem[2])
} else {
builder.WriteString("left")
} }
builder.WriteString(" join ")
if withSql != "" || strings.Contains(joinitem[0], "select ") || strings.HasPrefix(joinitem[0], "(") || len(joinitem) > 4 {
builder.WriteString(joinitem[0])
} else {
builder.WriteString(getTableName(dbName, joinitem[0]))
}
builder.WriteString(" on ")
builder.WriteString(joinitem[1])
boo = true
}
if boo {
sql_str = builder.String()
} }
} }
if len(where) > 0 || len(where_or) > 0 { if len(where) > 0 || len(where_or) > 0 {
@ -392,7 +466,10 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
} }
for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题 for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题
if DB_PROVIDER == "PgsqlDb" {
sql_str = sqlx.Rebind(sqlx.DOLLAR, sql_str)
sql_str = strings.Replace(sql_str, "`", `"`, -1)
}
rows, err = db.Query(sql_str, valueList...) rows, err = db.Query(sql_str, valueList...)
if err == nil { if err == nil {
@ -406,6 +483,7 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
} }
if err != nil { if err != nil {
log.Println("DB error:", err)
rows.Close() rows.Close()
return count, info, err return count, info, err
} }
@ -436,6 +514,7 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
} }
rows.Close() rows.Close()
if rowerr != nil { if rowerr != nil {
log.Println("DB row error:", rowerr)
return count, info, rowerr return count, info, rowerr
} }
return count, info, nil return count, info, nil
@ -447,7 +526,7 @@ func GetRow(dbName, table_name, alias string, titles string, join [][]string, wh
* @param dbName 数据表名 * @param dbName 数据表名
* @param title 查询字段名 * @param title 查询字段名
*/ */
func FetchRows(dbName, table_name, alias string, titles string, join [][]string, where, where_or []string, valueList []interface{}, orderby, groupby, having string, page int, page_size int, debug bool) (int, []map[string]string, error) {
func FetchRows(dbName, table_name, alias string, titles string, with, join [][]string, where, where_or []string, valueList []interface{}, orderby, groupby, having string, page int, page_size int, debug bool) (int, []map[string]string, error) {
var count int = 0 var count int = 0
list := make([]map[string]string, 0) list := make([]map[string]string, 0)
@ -455,7 +534,30 @@ func FetchRows(dbName, table_name, alias string, titles string, join [][]string,
return count, list, errors.New("没有数据表") return count, list, errors.New("没有数据表")
} }
table := "" table := ""
if strings.Contains(table_name, "select ") {
withSql := ""
if len(with) > 0 {
var builder strings.Builder
builder.WriteString("WITH ")
boo := false
for k, v := range with {
if len(v) < 2 {
continue
}
if k != 0 {
builder.WriteString(", ")
}
builder.WriteString(v[1])
builder.WriteString(" as (")
builder.WriteString(v[0])
builder.WriteString(")")
boo = true
}
if boo {
builder.WriteString(" ")
withSql = builder.String()
}
}
if withSql != "" || strings.Contains(table_name, "select ") || strings.HasPrefix(table, "(") {
table = table_name table = table_name
} else { } else {
table = getTableName(dbName, table_name) table = getTableName(dbName, table_name)
@ -468,10 +570,11 @@ func FetchRows(dbName, table_name, alias string, titles string, join [][]string,
} else { } else {
title = "*" title = "*"
} }
if DB_PROVIDER == "TencentDB" { if DB_PROVIDER == "TencentDB" {
sql_str = helper.StringJoin("/*slave*/ select ", title)
sql_str = helper.StringJoin("/*slave*/ ", withSql, " select ", title)
} else { } else {
sql_str = helper.StringJoin("select ", title)
sql_str = helper.StringJoin(withSql, "select ", title)
} }
if alias != "" { if alias != "" {
table = helper.StringJoin(table, " as ", alias) table = helper.StringJoin(table, " as ", alias)
@ -480,17 +583,31 @@ func FetchRows(dbName, table_name, alias string, titles string, join [][]string,
sql_str = helper.StringJoin(sql_str, " from ", table) sql_str = helper.StringJoin(sql_str, " from ", table)
if len(join) > 0 { if len(join) > 0 {
var builder strings.Builder
builder.WriteString(sql_str)
boo := false
for _, joinitem := range join { for _, joinitem := range join {
if len(joinitem) < 2 { if len(joinitem) < 2 {
continue continue
} }
if len(joinitem) == 4 {
sql_str = helper.StringJoin(sql_str, " ", joinitem[2], " join ", joinitem[0], " on ", joinitem[1])
} else if len(joinitem) == 3 {
sql_str = helper.StringJoin(sql_str, " ", joinitem[2], " join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1])
} else { //默认左连接
sql_str = helper.StringJoin(sql_str, " left join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1])
builder.WriteString(" ")
if len(joinitem) >= 3 {
builder.WriteString(joinitem[2])
} else {
builder.WriteString("left")
} }
builder.WriteString(" join ")
if withSql != "" || strings.Contains(joinitem[0], "select ") || strings.HasPrefix(joinitem[0], "(") || len(joinitem) >= 4 {
builder.WriteString(joinitem[0])
} else {
builder.WriteString(getTableName(dbName, joinitem[0]))
}
builder.WriteString(" on ")
builder.WriteString(joinitem[1])
boo = true
}
if boo {
sql_str = builder.String()
} }
} }
@ -528,7 +645,11 @@ func FetchRows(dbName, table_name, alias string, titles string, join [][]string,
from := strconv.Itoa((page - 1) * page_size) from := strconv.Itoa((page - 1) * page_size)
offset := strconv.Itoa(page_size) offset := strconv.Itoa(page_size)
if from != "" && offset != "" { if from != "" && offset != "" {
sql_str = helper.StringJoin(sql_str, " limit ", from, " , ", offset)
if DB_PROVIDER == "PgsqlDb" {
sql_str = helper.StringJoin(sql_str, " limit ", offset, " OFFSET ", from)
} else {
sql_str = helper.StringJoin(sql_str, " limit ", from, " , ", offset)
}
} }
} }
if debug { if debug {
@ -554,7 +675,10 @@ func FetchRows(dbName, table_name, alias string, titles string, join [][]string,
var err error var err error
var queryNum int = 0 var queryNum int = 0
for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题 for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题
if DB_PROVIDER == "PgsqlDb" {
sql_str = sqlx.Rebind(sqlx.DOLLAR, sql_str)
sql_str = strings.Replace(sql_str, "`", `"`, -1)
}
rows, err = db.Query(sql_str, valueList...) rows, err = db.Query(sql_str, valueList...)
if err == nil { if err == nil {
@ -632,7 +756,6 @@ func GetList(dbName, table string, title string, where map[string]string, limit
if dbName == "" && table == "" { if dbName == "" && table == "" {
return list, errors.New("没有数据表") return list, errors.New("没有数据表")
} }
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
@ -660,7 +783,12 @@ func GetList(dbName, table string, title string, where map[string]string, limit
from = limit["from"] from = limit["from"]
} }
if offset != "0" && from != "" { if offset != "0" && from != "" {
limitStr += " limit " + from + "," + offset
if DB_PROVIDER == "PgsqlDb" {
limitStr += " limit " + offset + " OFFSET " + from
} else {
limitStr += " limit " + from + "," + offset
}
} }
} }
@ -694,8 +822,13 @@ func GetList(dbName, table string, title string, where map[string]string, limit
} }
for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题
rows, err = DB.Query("select "+title+" from "+dbName+" where "+strings.Join(whereStr, " and ")+" "+limitStr, valueList...)
var Sql string
Sql = "select " + title + " from " + dbName + " where " + strings.Join(whereStr, " and ") + " " + limitStr
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
rows, err = DB.Query(Sql, valueList...)
if err == nil { if err == nil {
break break
@ -759,7 +892,6 @@ func GetTotal(dbName, table string, args ...string) (total int) {
if dbName == "" && table == "" { if dbName == "" && table == "" {
return return
} }
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
@ -777,7 +909,6 @@ func GetTotal(dbName, table string, args ...string) (total int) {
var queryNum int = 0 var queryNum int = 0
for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题
rows, err = DB.Query("select count(" + title + ") as count from " + dbName + " limit 1") rows, err = DB.Query("select count(" + title + ") as count from " + dbName + " limit 1")
if err == nil { if err == nil {
@ -861,7 +992,13 @@ func GetCount(dbName, table string, where map[string]string, args ...string) (to
for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题
rows, err = DB.Query("select count("+title+") as count from "+dbName+" where "+strings.Join(whereStr, " and ")+" limit 1", valueList...)
var Sql string
Sql = "select count(" + title + ") as count from " + dbName + " where " + strings.Join(whereStr, " and ") + " limit 1"
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
rows, err = DB.Query(Sql, valueList...)
if err == nil { if err == nil {
break break
@ -920,6 +1057,10 @@ func DoQuery(args ...interface{}) ([]map[string]string, error) {
for queryNum < 3 { //如发生错误,继续查询5次,防止数据库连接断开问题 for queryNum < 3 { //如发生错误,继续查询5次,防止数据库连接断开问题
if len(args) > 1 { if len(args) > 1 {
if DB_PROVIDER == "PgsqlDb" {
queryStr = sqlx.Rebind(sqlx.DOLLAR, queryStr)
queryStr = strings.Replace(queryStr, "`", `"`, -1)
}
rows, err = DB.Query(queryStr, args[1:]...) //strings.Join(args[1:], ",") rows, err = DB.Query(queryStr, args[1:]...) //strings.Join(args[1:], ",")
if err != nil { if err != nil {
log.Println("ERROR|DoQuery error:", err) log.Println("ERROR|DoQuery error:", err)


+ 3
- 1
go.mod View File

@ -4,6 +4,8 @@ go 1.14
require ( require (
git.tetele.net/tgo/helper v0.1.0 git.tetele.net/tgo/helper v0.1.0
gitee.com/opengauss/openGauss-connector-go-pq v1.0.7
github.com/denisenkom/go-mssqldb v0.11.0 github.com/denisenkom/go-mssqldb v0.11.0
github.com/go-sql-driver/mysql v1.5.0
github.com/go-sql-driver/mysql v1.8.1
github.com/jmoiron/sqlx v1.4.0
) )

+ 109
- 3
go.sum View File

@ -1,11 +1,117 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.tetele.net/tgo/helper v0.1.0 h1:ZdsBXUWX3+22ZzHTZRldBfBsQwu+CwUH8qScUvpgimE= git.tetele.net/tgo/helper v0.1.0 h1:ZdsBXUWX3+22ZzHTZRldBfBsQwu+CwUH8qScUvpgimE=
git.tetele.net/tgo/helper v0.1.0/go.mod h1:shYQE/hvMy3fOE8JXKGxvywOXiz3M5Nw4e+u7HR8+NY= git.tetele.net/tgo/helper v0.1.0/go.mod h1:shYQE/hvMy3fOE8JXKGxvywOXiz3M5Nw4e+u7HR8+NY=
gitee.com/opengauss/openGauss-connector-go-pq v1.0.7 h1:plLidoldV5RfMU6i/I+tvRKtP3sfDyUzQ//HGXLLsZo=
gitee.com/opengauss/openGauss-connector-go-pq v1.0.7/go.mod h1:2UEp+ug6ls6C0pLfZgBn7VBzBntFUzxJuy+6FlQ7qyI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI=
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 69
- 11
prepare.go View File

@ -3,6 +3,7 @@ package dbquery
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"github.com/jmoiron/sqlx"
"log" "log"
"strings" "strings"
@ -41,8 +42,11 @@ func StmtForRead(dbName, table string, title string, where []string, limit map[s
offset = limit["offset"] offset = limit["offset"]
} }
if from != "" && offset != "" { if from != "" && offset != "" {
limitStr += " limit " + from + "," + offset
if DB_PROVIDER == "PgsqlDb" {
limitStr += " limit " + offset + " OFFSET " + from
} else {
limitStr += " limit " + from + "," + offset
}
} }
} }
@ -52,7 +56,13 @@ func StmtForRead(dbName, table string, title string, where []string, limit map[s
if len(where) > 0 { if len(where) > 0 {
// log.Println("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + limitStr) // log.Println("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + limitStr)
stmt, err = DB.Prepare("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + limitStr)
var Sql string
Sql = "SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + limitStr
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
stmt, err = DB.Prepare(Sql)
} else { } else {
// log.Println("SELECT " + title + " FROM " + dbName + limitStr) // log.Println("SELECT " + title + " FROM " + dbName + limitStr)
stmt, err = DB.Prepare("SELECT " + title + " FROM " + dbName + limitStr) stmt, err = DB.Prepare("SELECT " + title + " FROM " + dbName + limitStr)
@ -186,8 +196,13 @@ func StmtForUpdate(dbName, table string, data []string, where []string) (*sql.St
var stmt *sql.Stmt var stmt *sql.Stmt
var err error var err error
stmt, err = DB.Prepare("update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and "))
var Sql string
Sql = "update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and ")
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
stmt, err = DB.Prepare(Sql)
return stmt, err return stmt, err
} }
@ -224,7 +239,35 @@ func StmtForInsert(dbName, table string, data []string) (*sql.Stmt, error) {
var stmt *sql.Stmt var stmt *sql.Stmt
var err error var err error
stmt, err = DB.Prepare("insert into " + dbName + " set " + strings.Join(data, " , "))
var sql string
if DB_PROVIDER == "PgsqlDb" {
insert_data := []string{}
value_data := []string{}
for _, rv := range data {
dv := strings.Split(rv, "=")
if len(dv) < 2 {
return nil, errors.New("参数错误,条件值错误,=号不存在")
}
if strings.Contains(rv, "?") {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, "?")
} else {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, dv[1])
}
}
sql = helper.StringJoin("insert into ", dbName, " ("+strings.Join(insert_data, " , ")+")", " VALUES ", "("+strings.Join(value_data, " , ")+")", " RETURNING id")
} else {
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(data, " , "))
}
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
//stmt, err = DB.Prepare("insert into " + dbName + " set " + strings.Join(data, " , "))
stmt, err = DB.Prepare(sql)
return stmt, err return stmt, err
} }
@ -234,11 +277,23 @@ func StmtForInsert(dbName, table string, data []string) (*sql.Stmt, error) {
* @return lastId error * @return lastId error
*/ */
func StmtForInsertExec(stmt *sql.Stmt, valuelist []interface{}) (int64, error) { func StmtForInsertExec(stmt *sql.Stmt, valuelist []interface{}) (int64, error) {
res, err := stmt.Exec(valuelist...)
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
if DB_PROVIDER == "PgsqlDb" {
row := stmt.QueryRow(valuelist...)
var id int64
err = row.Scan(&id) // 扫描 RETURNING 返回的 ID
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
return id, nil
} else {
res, err := stmt.Exec(valuelist...)
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
return res.LastInsertId()
} }
return res.LastInsertId()
} }
/** /**
@ -350,7 +405,10 @@ func StmtForQuery(querysql string) (*sql.Stmt, error) {
var stmt *sql.Stmt var stmt *sql.Stmt
var err error var err error
if DB_PROVIDER == "PgsqlDb" {
querysql = sqlx.Rebind(sqlx.DOLLAR, querysql)
querysql = strings.Replace(querysql, "`", `"`, -1)
}
stmt, err = DB.Prepare(querysql) stmt, err = DB.Prepare(querysql)
return stmt, err return stmt, err


+ 91
- 30
transaction.go View File

@ -6,6 +6,8 @@ package dbquery
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"git.tetele.net/tgo/helper"
"github.com/jmoiron/sqlx"
"log" "log"
"strings" "strings"
"time" "time"
@ -25,7 +27,7 @@ func TxInsert(tx *sql.Tx, dbname, table string, data map[string]string) (int64,
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
dbName = getTableName(dbName, table)
dbName = getTableName(dbname, table)
} }
if len(data) < 1 { if len(data) < 1 {
return 0, errors.New("参数错误,没有要写入的数据") return 0, errors.New("参数错误,没有要写入的数据")
@ -43,16 +45,34 @@ func TxInsert(tx *sql.Tx, dbname, table string, data map[string]string) (int64,
valueList[i] = value valueList[i] = value
i++ i++
} }
result, err := tx.Exec("insert into "+dbName+" ("+strings.Join(keyList, ",")+") value("+strings.Join(keyStr, ",")+")", valueList...)
if err != nil {
log.Println("ERROR", "insert into ", dbName, "error:", err)
return insertId, err
if DB_PROVIDER == "PgsqlDb" {
var Sql string
Sql = "insert into " + dbName + " (" + strings.Join(keyList, ",") + ") values (" + strings.Join(keyStr, ",") + ")"
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
Sql = helper.StringJoin(Sql, " RETURNING id")
stmt, err = tx.Prepare(Sql)
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
row := stmt.QueryRow(valueList...)
var id int64
err = row.Scan(&id) // 扫描 RETURNING 返回的 ID
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
return id, nil
} else { } else {
insertId, _ = result.LastInsertId()
time.Sleep(time.Second * 2)
return insertId, nil
result, err := tx.Exec("insert into "+dbName+" ("+strings.Join(keyList, ",")+") value("+strings.Join(keyStr, ",")+")", valueList...)
if err != nil {
log.Println("ERROR", "insert into ", dbName, "error:", err)
return insertId, err
} else {
insertId, _ = result.LastInsertId()
time.Sleep(time.Second * 2)
return insertId, nil
}
} }
} }
@ -84,28 +104,48 @@ func TxPreInsert(tx *sql.Tx, dbname, table string, data map[string]interface{})
var field []string = make([]string, len(data)) var field []string = make([]string, len(data))
var valuelist []interface{} = make([]interface{}, len(data)) var valuelist []interface{} = make([]interface{}, len(data))
insert_data := []string{}
value_data := []string{}
var i int = 0 var i int = 0
for key, item := range data { for key, item := range data {
field[i] = key + "=?" field[i] = key + "=?"
valuelist[i] = item valuelist[i] = item
i++ i++
}
insert_data = append(insert_data, key)
value_data = append(value_data, "?")
}
if DB_PROVIDER == "PgsqlDb" {
Sql := helper.StringJoin("insert into ", dbName, " ("+strings.Join(insert_data, " , ")+")", " VALUES ", "("+strings.Join(value_data, " , ")+")", " RETURNING id")
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
stmt, err = tx.Prepare(Sql)
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
row := stmt.QueryRow(valuelist...)
var id int64
err = row.Scan(&id) // 扫描 RETURNING 返回的 ID
if err != nil {
return 0, errors.New("创建失败:" + err.Error())
}
return id, nil
} else {
sql := "insert into " + dbName + " set " + strings.Join(field, " , ")
stmt, err = tx.Prepare(sql)
sql := "insert into " + dbName + " set " + strings.Join(field, " , ")
stmt, err = tx.Prepare(sql)
if err != nil {
log.Println("insert prepare error:", sql, err)
return 0, errors.New("insert prepare error:" + err.Error())
}
result, err := stmt.Exec(valuelist...)
if err != nil {
log.Println("insert exec error:", sql, valuelist, err)
return 0, errors.New("insert exec error:" + err.Error())
if err != nil {
log.Println("insert prepare error:", sql, err)
return 0, errors.New("insert prepare error:" + err.Error())
}
result, err := stmt.Exec(valuelist...)
if err != nil {
log.Println("insert exec error:", sql, valuelist, err)
return 0, errors.New("insert exec error:" + err.Error())
}
insertId, _ := result.LastInsertId()
return insertId, nil
} }
insertId, _ := result.LastInsertId()
return insertId, nil
} }
@ -160,7 +200,13 @@ func TxUpdate(tx *sql.Tx, dbname, table string, data map[string]string, where ma
log.Println("ERROR", "update", dbName, "error, params empty") log.Println("ERROR", "update", dbName, "error, params empty")
return rowsAffected, errors.New("params empty") return rowsAffected, errors.New("params empty")
} }
result, err := tx.Exec("update "+dbName+" set "+strings.Join(keyList, " , ")+" where "+strings.Join(whereStr, " and "), valueList...)
var Sql string
Sql = "update " + dbName + " set " + strings.Join(keyList, " , ") + " where " + strings.Join(whereStr, " and ")
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
result, err := tx.Exec(Sql, valueList...)
if err != nil { if err != nil {
log.Println("ERROR", "update", dbName, "error:", err) log.Println("ERROR", "update", dbName, "error:", err)
@ -186,7 +232,7 @@ func TxPreUpdate(tx *sql.Tx, dbname, table string, data []string, where []string
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
dbName = getTableName(dbName, table)
dbName = getTableName(dbname, table)
} }
if len(where) < 1 { if len(where) < 1 {
@ -198,7 +244,10 @@ func TxPreUpdate(tx *sql.Tx, dbname, table string, data []string, where []string
var stmt *sql.Stmt var stmt *sql.Stmt
sql := "update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and ") sql := "update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and ")
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = tx.Prepare(sql) stmt, err = tx.Prepare(sql)
if err != nil { if err != nil {
@ -228,7 +277,7 @@ func TxDelete(tx *sql.Tx, dbname, table string, where map[string]string, del_cou
if strings.Contains(table, "select ") { if strings.Contains(table, "select ") {
dbName = table dbName = table
} else { } else {
dbName = getTableName(dbName, table)
dbName = getTableName(dbname, table)
} }
if len(where) < 1 { if len(where) < 1 {
return count, errors.New("参数错误,没有删除条件") return count, errors.New("参数错误,没有删除条件")
@ -260,7 +309,13 @@ func TxDelete(tx *sql.Tx, dbname, table string, where map[string]string, del_cou
limitStr = " limit " + del_count[0] limitStr = " limit " + del_count[0]
} }
result, err := tx.Exec("delete from "+dbName+" where "+strings.Join(keyList, " and ")+limitStr, valueList...)
var Sql string
Sql = "delete from " + dbName + " where " + strings.Join(keyList, " and ") + limitStr
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
result, err := tx.Exec(Sql, valueList...)
if err != nil { if err != nil {
log.Println("ERROR", "delete from", dbName, "error:", err) log.Println("ERROR", "delete from", dbName, "error:", err)
@ -296,7 +351,13 @@ func TxForRead(tx *sql.Tx, dbName, table string, title string, where []string) (
if len(where) > 0 { if len(where) > 0 {
// log.Println("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + " FOR UPDATE") // log.Println("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + " FOR UPDATE")
stmt, err = tx.Prepare("SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + " FOR UPDATE")
var Sql string
Sql = "SELECT " + title + " FROM " + dbName + " where " + strings.Join(where, " and ") + " FOR UPDATE"
if DB_PROVIDER == "PgsqlDb" {
Sql = sqlx.Rebind(sqlx.DOLLAR, Sql)
Sql = strings.Replace(Sql, "`", `"`, -1)
}
stmt, err = tx.Prepare(Sql)
} else { } else {
// log.Println("SELECT " + title + " FROM " + dbName + " FOR UPDATE") // log.Println("SELECT " + title + " FROM " + dbName + " FOR UPDATE")
stmt, err = tx.Prepare("SELECT " + title + " FROM " + dbName + " FOR UPDATE") stmt, err = tx.Prepare("SELECT " + title + " FROM " + dbName + " FOR UPDATE")


+ 167
- 15
transaction_chain.go View File

@ -6,6 +6,7 @@ package dbquery
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"github.com/jmoiron/sqlx"
"log" "log"
"strconv" "strconv"
"strings" "strings"
@ -34,6 +35,7 @@ type TxQuery struct {
conn *sql.DB conn *sql.DB
tx *sql.Tx tx *sql.Tx
debug bool debug bool
with [][]string //[[临时表的sql语句,临时表的名称]]
} }
func NewTxQuery(t ...string) *TxQuery { func NewTxQuery(t ...string) *TxQuery {
@ -109,6 +111,14 @@ func (this *TxQuery) Where(where string) *TxQuery {
this.where = append(this.where, where) this.where = append(this.where, where)
return this return this
} }
func (this *TxQuery) With(with []string) *TxQuery {
this.with = append(this.with, with)
return this
}
func (this *TxQuery) Withs(withs [][]string) *TxQuery {
this.with = append(this.with, withs...)
return this
}
func (this *TxQuery) Wheres(wheres []string) *TxQuery { func (this *TxQuery) Wheres(wheres []string) *TxQuery {
if len(wheres) > 0 { if len(wheres) > 0 {
this.where = append(this.where, wheres...) this.where = append(this.where, wheres...)
@ -147,6 +157,26 @@ func (this *TxQuery) Join(join []string) *TxQuery {
this.join = append(this.join, join) this.join = append(this.join, join)
return this return this
} }
/**
* 左连接
* 2023/08/10
* gz
*/
func (this *TxQuery) LeftJoin(table_name string, condition string) *TxQuery {
this.join = append(this.join, []string{table_name, condition, "left"})
return this
}
/**
* 右连接
* 2023/08/10
* gz
*/
func (this *TxQuery) RightJoin(table_name string, condition string) *TxQuery {
this.join = append(this.join, []string{table_name, condition, "right"})
return this
}
func (this *TxQuery) Data(data string) *TxQuery { func (this *TxQuery) Data(data string) *TxQuery {
this.data = append(this.data, data) this.data = append(this.data, data)
return this return this
@ -177,16 +207,46 @@ func (this *TxQuery) Clean() *TxQuery {
this.save_data = this.save_data[0:0] this.save_data = this.save_data[0:0]
this.upd_field = this.upd_field[0:0] this.upd_field = this.upd_field[0:0]
this.having = "" this.having = ""
this.alias = ""
this.with = this.with[0:0]
return this return this
} }
//构造子查询
// 返回表名
func (this *TxQuery) GetTableName(table string) string {
return getTableName(this.dbname, table)
}
// 构造子查询
func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) { func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) {
if this.dbname == "" && this.table == "" { if this.dbname == "" && this.table == "" {
return nil, errors.New("参数错误,没有数据表") return nil, errors.New("参数错误,没有数据表")
} }
var table = "" var table = ""
if strings.Contains(this.table, "select ") {
withSql := ""
if len(this.with) > 0 {
var builder strings.Builder
builder.WriteString("WITH ")
boo := false
for k, v := range this.with {
if len(v) < 2 {
continue
}
if k != 0 {
builder.WriteString(", ")
}
builder.WriteString(v[1])
builder.WriteString(" as (")
builder.WriteString(v[0])
builder.WriteString(")")
boo = true
}
if boo {
builder.WriteString(" ")
withSql = builder.String()
}
}
if withSql != "" || strings.Contains(this.table, "select ") || strings.HasPrefix(this.table, "(") {
table = this.table table = this.table
} else { } else {
table = getTableName(this.dbname, this.table) table = getTableName(this.dbname, this.table)
@ -199,7 +259,8 @@ func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) {
} else { } else {
title = "*" title = "*"
} }
sql = helper.StringJoin("select ", title)
sql = helper.StringJoin(withSql, "select ", title)
if this.alias != "" { if this.alias != "" {
table = helper.StringJoin(table, " as ", this.alias) table = helper.StringJoin(table, " as ", this.alias)
@ -208,15 +269,31 @@ func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) {
sql = helper.StringJoin(sql, " from ", table) sql = helper.StringJoin(sql, " from ", table)
if len(this.join) > 0 { if len(this.join) > 0 {
var builder strings.Builder
builder.WriteString(sql)
boo := false
for _, joinitem := range this.join { for _, joinitem := range this.join {
if len(joinitem) < 2 { if len(joinitem) < 2 {
continue 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])
builder.WriteString(" ")
if len(joinitem) >= 3 {
builder.WriteString(joinitem[2])
} else {
builder.WriteString("left")
} }
builder.WriteString(" join ")
if withSql != "" || strings.Contains(joinitem[0], "select ") || strings.HasPrefix(joinitem[0], "(") {
builder.WriteString(joinitem[0])
} else {
builder.WriteString(getTableName(this.dbname, joinitem[0]))
}
builder.WriteString(" on ")
builder.WriteString(joinitem[1])
boo = true
}
if boo {
sql = builder.String()
} }
} }
if len(this.where) > 0 || len(this.where_or) > 0 { if len(this.where) > 0 || len(this.where_or) > 0 {
@ -255,7 +332,12 @@ func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) {
from := strconv.Itoa((this.page - 1) * this.page_size) from := strconv.Itoa((this.page - 1) * this.page_size)
offset := strconv.Itoa(this.page_size) offset := strconv.Itoa(this.page_size)
if from != "" && offset != "" { if from != "" && offset != "" {
sql = helper.StringJoin(sql, " limit ", from, " , ", offset)
if DB_PROVIDER == "PgsqlDb" {
sql = helper.StringJoin(sql, " limit ", offset, " OFFSET ", from)
} else {
sql = helper.StringJoin(sql, " limit ", from, " , ", offset)
}
} }
} }
@ -272,13 +354,17 @@ func (this *TxQuery) BuildSelectSql() (map[string]interface{}, error) {
if condition_len != len(this.value) { if condition_len != len(this.value) {
return nil, errors.New("参数错误,条件值错误") return nil, errors.New("参数错误,条件值错误")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
return map[string]interface{}{ return map[string]interface{}{
"sql": sql, "sql": sql,
"value": this.value, "value": this.value,
}, nil }, nil
} }
//获取表格信息
// 获取表格信息
func (this *TxQuery) GetTableInfo(table string) (map[string]interface{}, error) { func (this *TxQuery) GetTableInfo(table string) (map[string]interface{}, error) {
field := []string{ field := []string{
"COLUMN_NAME", //字段名 "COLUMN_NAME", //字段名
@ -289,7 +375,10 @@ func (this *TxQuery) GetTableInfo(table string) (map[string]interface{}, error)
"IS_NULLABLE", //是否为空 "IS_NULLABLE", //是否为空
} }
sql := "select `" + strings.Join(field, "`,`") + "` from information_schema.COLUMNS where table_name = ? and table_schema = ?" sql := "select `" + strings.Join(field, "`,`") + "` from information_schema.COLUMNS where table_name = ? and table_schema = ?"
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmtSql, err := this.tx.Prepare(sql) stmtSql, err := this.tx.Prepare(sql)
if err != nil { if err != nil {
return nil, err return nil, err
@ -395,7 +484,10 @@ func (this *TxQuery) UpdateStmt() error {
if condition_len != len(this.value) { if condition_len != len(this.value) {
return errors.New("参数错误,条件值错误") return errors.New("参数错误,条件值错误")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.tx.Prepare(sql) stmt, err = this.tx.Prepare(sql)
if err != nil { if err != nil {
@ -498,6 +590,9 @@ func (this *TxQuery) UpdateAllStmt() error {
if len(valSql) > 1 { if len(valSql) > 1 {
setText = " value " setText = " value "
} }
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
}
sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","), " ON DUPLICATE KEY UPDATE ", strings.Join(updSql, " , ")) sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","), " ON DUPLICATE KEY UPDATE ", strings.Join(updSql, " , "))
if this.debug { if this.debug {
@ -513,6 +608,10 @@ func (this *TxQuery) UpdateAllStmt() error {
if conditionLen != len(this.value) { if conditionLen != len(this.value) {
return errors.New("参数错误,条件值数量不匹配") return errors.New("参数错误,条件值数量不匹配")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.tx.Prepare(sql) stmt, err = this.tx.Prepare(sql)
if err != nil { if err != nil {
@ -534,8 +633,28 @@ func (this *TxQuery) CreateStmt() error {
dbName := getTableName(this.dbname, this.table) dbName := getTableName(this.dbname, this.table)
var sql string var sql string
if DB_PROVIDER == "PgsqlDb" {
insert_data := []string{}
value_data := []string{}
for _, rv := range this.data {
dv := strings.Split(rv, "=")
if len(dv) < 2 {
return errors.New("参数错误,条件值错误,=号不存在")
}
if strings.Contains(rv, "?") {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, "?")
} else {
insert_data = append(insert_data, dv[0])
value_data = append(value_data, dv[1])
}
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
}
sql = helper.StringJoin("insert into ", dbName, " ("+strings.Join(insert_data, " , ")+")", " VALUES ", "("+strings.Join(value_data, " , ")+")", " RETURNING id")
} else {
sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
}
//sql = helper.StringJoin("insert into ", dbName, " set ", strings.Join(this.data, " , "))
if this.debug { if this.debug {
log.Println("insert sql:", sql, this.value) log.Println("insert sql:", sql, this.value)
@ -551,7 +670,10 @@ func (this *TxQuery) CreateStmt() error {
if condition_len != len(this.value) { if condition_len != len(this.value) {
return errors.New("参数错误,条件值错误") return errors.New("参数错误,条件值错误")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.tx.Prepare(sql) stmt, err = this.tx.Prepare(sql)
if err != nil { if err != nil {
@ -622,6 +744,9 @@ func (this *TxQuery) CreateAllStmt() error {
if len(valSql) > 1 { if len(valSql) > 1 {
setText = " value " setText = " value "
} }
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
}
sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ",")) sql = helper.StringJoin("insert into ", dbName, " (", strings.Join(this.data, " , "), ")", setText, strings.Join(valSql, ","))
if len(this.value) == 0 { if len(this.value) == 0 {
return errors.New("参数错误,条件值错误") return errors.New("参数错误,条件值错误")
@ -640,7 +765,11 @@ func (this *TxQuery) CreateAllStmt() error {
if conditionLen != len(this.value) { if conditionLen != len(this.value) {
return errors.New("参数错误,条件值数量不匹配") return errors.New("参数错误,条件值数量不匹配")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
sql = helper.StringJoin(sql, " RETURNING id")
}
stmt, err = this.tx.Prepare(sql) stmt, err = this.tx.Prepare(sql)
if err != nil { if err != nil {
@ -686,7 +815,10 @@ func (this *TxQuery) DeleteStmt() error {
if condition_len != len(this.value) { if condition_len != len(this.value) {
return errors.New("参数错误,条件值错误") return errors.New("参数错误,条件值错误")
} }
if DB_PROVIDER == "PgsqlDb" {
sql = sqlx.Rebind(sqlx.DOLLAR, sql)
sql = strings.Replace(sql, "`", `"`, -1)
}
stmt, err = this.tx.Prepare(sql) stmt, err = this.tx.Prepare(sql)
if err != nil { if err != nil {
@ -801,6 +933,26 @@ func (this *TxQuery) CreateAll() (int64, error) {
return StmtForInsertExec(this.stmt, this.value) return StmtForInsertExec(this.stmt, this.value)
} }
/**
* 执行原生sql
* return error
*/
func (this *TxQuery) ExecSql(sql string) (int64, error) {
if this.debug {
log.Println("ExecSql sql:", sql)
}
stmt, err = this.tx.Prepare(sql)
if err != nil {
return 0, err
}
res, err := stmt.Exec()
if err != nil {
return 0, errors.New("执行失败:" + err.Error())
}
return res.RowsAffected()
}
/** /**
* 提交 * 提交
*/ */


Loading…
Cancel
Save