| @ -0,0 +1,32 @@ | |||
| # dbquery | |||
| 腾讯云mariadb一主多从数据库操作 | |||
| ## 链式查询使用 | |||
| ``` | |||
| 查询单条记录 | |||
| map,err := new(Query).Db(dbname).Table(tablename).Where("id=?").Where("name=?").Value(1).Value("test").Find() | |||
| 查询列表 | |||
| list,err := new(Query).Db(dbname).Table(tablename).Where("id=?").Where("name=?").Value(1).Value("test").Select() | |||
| 条件"或" | |||
| list,err := new(Query).Db(dbname).Table(tablename).Where("id=?").Where("name=?").WhereOr("mobile=?").Value(1).Value("test").Value("22").Select() | |||
| 联表查 | |||
| 使用Join | |||
| list,err := new(Query).Db(dbname).Table(tablename).Join([]string{jointable,tablename.id=jointable.cid,"LEFT"}).Where("id=?").Where("name=?").Value(1).Value("test").Select() | |||
| 更新 | |||
| ret,err := new(Query).Db(dbname).Table(tablename).Data("name=?").Data("depart=?").Value("xxx").Value("test").Update() | |||
| 插入 | |||
| ret,err := new(Query).Db(dbname).Table(tablename).Data("name=?").Data("depart=?").Value("xxx").Value("test").Create() | |||
| 删除 | |||
| ret,err := new(Query).Db(dbname).Table(tablename).Where("name=?").Where("depart=?").Value("xxx").Value("test").Delete() | |||
| ``` | |||
| @ -0,0 +1,502 @@ | |||
| package tencentdb | |||
| import ( | |||
| "database/sql" | |||
| "errors" | |||
| "log" | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| type Query 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 | |||
| debug bool | |||
| dbtype string | |||
| } | |||
| func NewQuery(t ...string) *Query { | |||
| return &Query{ | |||
| conn: DB, | |||
| dbtype: "mysql", | |||
| } | |||
| } | |||
| func (this *Query) Conn(conn *sql.DB) *Query { | |||
| this.conn = conn | |||
| return this | |||
| } | |||
| func (this *Query) ConnClose() error { | |||
| return this.conn.Close() | |||
| } | |||
| func (this *Query) Db(dbname string) *Query { | |||
| this.dbname = dbname | |||
| return this | |||
| } | |||
| func (this *Query) Table(tablename string) *Query { | |||
| this.table = tablename | |||
| return this | |||
| } | |||
| func (this *Query) Alias(tablename string) *Query { | |||
| this.alias = tablename | |||
| return this | |||
| } | |||
| func (this *Query) Title(title string) *Query { | |||
| this.title = title | |||
| return this | |||
| } | |||
| func (this *Query) Page(page int) *Query { | |||
| this.page = page | |||
| return this | |||
| } | |||
| func (this *Query) PageSize(page_num int) *Query { | |||
| this.page_size = page_num | |||
| return this | |||
| } | |||
| func (this *Query) Orderby(orderby string) *Query { | |||
| this.orderby = orderby | |||
| return this | |||
| } | |||
| func (this *Query) Where(where string) *Query { | |||
| this.where = append(this.where, where) | |||
| return this | |||
| } | |||
| func (this *Query) Wheres(wheres []string) *Query { | |||
| if len(wheres) > 0 { | |||
| this.where = append(this.where, wheres...) | |||
| } | |||
| return this | |||
| } | |||
| func (this *Query) WhereOr(where string) *Query { | |||
| this.where_or = append(this.where_or, where) | |||
| return this | |||
| } | |||
| func (this *Query) Value(value interface{}) *Query { | |||
| this.value = append(this.value, value) | |||
| return this | |||
| } | |||
| func (this *Query) Values(values []interface{}) *Query { | |||
| this.value = append(this.value, values...) | |||
| return this | |||
| } | |||
| func (this *Query) Join(join []string) *Query { | |||
| this.join = append(this.join, join) | |||
| return this | |||
| } | |||
| func (this *Query) Data(data string) *Query { | |||
| this.data = append(this.data, data) | |||
| return this | |||
| } | |||
| func (this *Query) Datas(datas []string) *Query { | |||
| this.data = append(this.data, datas...) | |||
| return this | |||
| } | |||
| func (this *Query) Debug(debug bool) *Query { | |||
| this.debug = debug | |||
| return this | |||
| } | |||
| /* | |||
| * 清理上次查询 | |||
| */ | |||
| func (this *Query) Clean() *Query { | |||
| 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 *Query) QueryStmt() error { | |||
| if this.dbname == "" && this.table == "" { | |||
| return errors.New("参数错误,没有数据表") | |||
| } | |||
| table := getTableName(this.dbname, this.table, this.dbtype) | |||
| // var err error | |||
| var sql, title string | |||
| if this.title != "" { | |||
| title = this.title | |||
| } else { | |||
| title = "*" | |||
| } | |||
| sql = StringJoin("/*slave*/ select ", title) | |||
| if this.alias != "" { | |||
| table = StringJoin(table, " as ", this.alias) | |||
| } | |||
| sql = StringJoin(sql, " from ", table) | |||
| if len(this.join) > 0 { | |||
| for _, joinitem := range this.join { | |||
| if len(joinitem) < 2 { | |||
| continue | |||
| } | |||
| if len(joinitem) == 3 { | |||
| sql = StringJoin(sql, " ", joinitem[2], " join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1]) | |||
| } else { //默认左连接 | |||
| sql = StringJoin(sql, " left join ", getTableName(this.dbname, joinitem[0], this.dbtype), " on ", joinitem[1]) | |||
| } | |||
| } | |||
| } | |||
| if len(this.where) > 0 || len(this.where_or) > 0 { | |||
| sql = StringJoin(sql, " where ") | |||
| } | |||
| if len(this.where) > 0 { | |||
| sql = StringJoin(sql, " (", strings.Join(this.where, " and "), " ) ") | |||
| } | |||
| if len(this.where_or) > 0 { | |||
| if len(this.where) > 0 { | |||
| sql = StringJoin(sql, " or ", strings.Join(this.where_or, " or ")) | |||
| } else { | |||
| sql = StringJoin(sql, strings.Join(this.where_or, " or ")) | |||
| } | |||
| } | |||
| if this.orderby != "" { | |||
| sql = 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 = 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("参数错误,条件值错误") | |||
| } | |||
| if this.conn == nil { | |||
| this.conn = DB | |||
| } | |||
| stmt, err = this.conn.Prepare(sql) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| this.stmt = stmt | |||
| return nil | |||
| } | |||
| // 拼更新sql | |||
| func (this *Query) UpdateStmt() error { | |||
| if this.dbname == "" && this.table == "" { | |||
| return errors.New("参数错误,没有数据表") | |||
| } | |||
| if len(this.where) < 1 { | |||
| return errors.New("参数错误,缺少条件") | |||
| } | |||
| dbName := getTableName(this.dbname, this.table, this.dbtype) | |||
| var sql string | |||
| sql = StringJoin("update ", dbName, " set ", strings.Join(this.data, " , ")) | |||
| sql = 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("参数错误,条件值错误") | |||
| } | |||
| if this.conn == nil { | |||
| this.conn = DB | |||
| } | |||
| stmt, err = this.conn.Prepare(sql) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| this.stmt = stmt | |||
| return nil | |||
| } | |||
| // 拼插入sql | |||
| func (this *Query) CreateStmt() error { | |||
| if this.dbname == "" && this.table == "" { | |||
| return errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName := getTableName(this.dbname, this.table, this.dbtype) | |||
| var sql string | |||
| sql = 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("参数错误,条件值错误") | |||
| } | |||
| if this.conn == nil { | |||
| this.conn = DB | |||
| } | |||
| stmt, err = this.conn.Prepare(sql) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| this.stmt = stmt | |||
| return nil | |||
| } | |||
| // 拼删除sql | |||
| func (this *Query) DeleteStmt() error { | |||
| if this.dbname == "" && this.table == "" { | |||
| return errors.New("参数错误,没有数据表") | |||
| } | |||
| if len(this.where) < 1 { | |||
| return errors.New("参数错误,缺少条件") | |||
| } | |||
| dbName := getTableName(this.dbname, this.table, this.dbtype) | |||
| var sql string | |||
| sql = StringJoin("delete from ", dbName, " where ", strings.Join(this.where, " and ")) | |||
| if this.page_size > 0 { | |||
| sql = 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("参数错误,条件值错误") | |||
| } | |||
| if this.conn == nil { | |||
| this.conn = DB | |||
| } | |||
| stmt, err = this.conn.Prepare(sql) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| this.stmt = stmt | |||
| return nil | |||
| } | |||
| /** | |||
| * 执行查询列表 | |||
| * return list error | |||
| */ | |||
| func (this *Query) Select() ([]map[string]string, error) { | |||
| conn, err := connectDb(dbhost_slaver, dbuser_slaver, dbpwd_slaver, dbname_slaver, dbport_slaver, 1, 0) | |||
| if err != nil { | |||
| log.Println("new query error:", err) | |||
| } | |||
| if conn == nil { | |||
| log.Println("Err: no conn") | |||
| } | |||
| _, rows, err := FetchRows(conn, this.dbname, this.table, this.alias, this.title, this.join, | |||
| this.where, this.where_or, this.value, this.orderby, this.page, this.page_size, this.debug) | |||
| conn.Close() | |||
| return rows, err | |||
| } | |||
| /** | |||
| * 执行查询多条数据 | |||
| * return row error | |||
| * 2022/01/05 | |||
| */ | |||
| func (this *Query) List() ([]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("缺少必要参数") | |||
| } | |||
| list, err := StmtForQueryList(this.stmt, this.value) | |||
| return list, err | |||
| } | |||
| /** | |||
| * 执行查询一条数据 | |||
| * return row error | |||
| */ | |||
| func (this *Query) Find() (map[string]string, error) { | |||
| conn, err := connectDb(dbhost_slaver, dbuser_slaver, dbpwd_slaver, dbname_slaver, dbport_slaver, 1, 0) | |||
| if err != nil { | |||
| log.Println("new query error:", err) | |||
| } | |||
| if conn == nil { | |||
| log.Println("Err: no conn") | |||
| } | |||
| _, row, err := GetRow(conn, this.dbname, this.table, this.alias, this.title, this.join, | |||
| this.where, this.where_or, this.value, this.orderby, this.debug) | |||
| conn.Close() | |||
| return row, err | |||
| } | |||
| /** | |||
| * 执行查询一条数据 | |||
| * return row error | |||
| * 2022/01/05 | |||
| */ | |||
| func (this *Query) Get() (map[string]string, error) { | |||
| this.page = 1 | |||
| this.page_size = 1 | |||
| err := this.QueryStmt() | |||
| if err != nil { | |||
| return map[string]string{}, err | |||
| } | |||
| if this.stmt == nil { | |||
| return nil, errors.New("缺少必要参数") | |||
| } | |||
| row, err := StmtForQueryRow(this.stmt, this.value) | |||
| return row, err | |||
| } | |||
| /** | |||
| * 执行更新 | |||
| * return is_updated error | |||
| */ | |||
| func (this *Query) Update() (int64, error) { | |||
| err := this.UpdateStmt() | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| ret, err := StmtForUpdateExec(this.stmt, this.value) | |||
| return ret, err | |||
| } | |||
| /** | |||
| * 执行删除 | |||
| * return is_delete error | |||
| */ | |||
| func (this *Query) Delete() (int64, error) { | |||
| err := this.DeleteStmt() | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| ret, err := StmtForUpdateExec(this.stmt, this.value) | |||
| return ret, err | |||
| } | |||
| /** | |||
| * 执行写入 | |||
| * return is_insert error | |||
| */ | |||
| func (this *Query) Create() (int64, error) { | |||
| err := this.CreateStmt() | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| ret, err := StmtForInsertExec(this.stmt, this.value) | |||
| return ret, err | |||
| } | |||
| @ -0,0 +1,21 @@ | |||
| package tencentdb | |||
| import ( | |||
| "testing" | |||
| ) | |||
| func Test_Chain(t *testing.T) { | |||
| ConnectSlaver("106.52.13.101", "yueheng_slaver", "yhslave^%*345Sr", "shop_test", "13306") | |||
| for i := 0; i < 10000; i++ { | |||
| t.Log("i:", i) | |||
| ret, err := NewQuery().Db("shop_test").Table("ttl_order_product").Alias("op"). | |||
| Join([]string{"ttl_product as p", "op.product_id=p.id"}). | |||
| Title("op.id,op.order_price,p.thumb").WhereOr("op.id =?").WhereOr("op.id = ?").Value(63).Value(64).Debug(true).Select() | |||
| t.Log(len(ret)) | |||
| // t.Log(ret) | |||
| t.Log(err) | |||
| } | |||
| } | |||
| @ -0,0 +1,187 @@ | |||
| package tencentdb | |||
| import ( | |||
| "database/sql" | |||
| "log" | |||
| "errors" | |||
| "strings" | |||
| "time" | |||
| _ "github.com/go-sql-driver/mysql" | |||
| ) | |||
| var DB *sql.DB | |||
| var dbhost_slaver, dbname_slaver, dbport_slaver, dbuser_slaver, dbpwd_slaver string //从库信息 | |||
| var use_slaver bool = false | |||
| func Connect(DBHOST, DBUSER, DBPWD, DBNAME, DBPORT string, conns ...int) error { | |||
| log.Println("database connectting...") | |||
| var dbConnErr error | |||
| if DBHOST != "" && DBUSER != "" && DBPWD != "" && DBPORT != "" { //&& DBNAME != "" | |||
| for i := 0; i < 10; i++ { | |||
| DB, dbConnErr = sql.Open("mysql", DBUSER+":"+DBPWD+"@tcp("+DBHOST+":"+DBPORT+")/"+DBNAME+"?charset=utf8mb4") | |||
| if dbConnErr != nil { | |||
| log.Println("ERROR", "can not connect to 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("database connected") | |||
| DB.SetConnMaxLifetime(time.Minute * 2) | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| return errors.New("db connection params errors") | |||
| } | |||
| return dbConnErr | |||
| } | |||
| func CloseConn() error { | |||
| return DB.Close() | |||
| } | |||
| func ConnectSlaver(DBHOST, DBUSER_SLAVER, DBPWD_SLAVER, DBNAME, DBPORT string, conns ...int) { | |||
| dbhost_slaver = DBHOST | |||
| dbuser_slaver = DBUSER_SLAVER | |||
| dbpwd_slaver = DBPWD_SLAVER | |||
| dbname_slaver = DBNAME | |||
| dbport_slaver = DBPORT | |||
| use_slaver = true | |||
| // log.Println("database connectting with slaver...") | |||
| // var dbConnErr error | |||
| // if DBHOST != "" && DBUSER_SLAVER != "" && DBPWD_SLAVER != "" && DBPORT != "" { //&& DBNAME != "" | |||
| // for i := 0; i < 10; i++ { | |||
| // SLAVER_DB, dbConnErr = sql.Open("mysql", DBUSER_SLAVER+":"+DBPWD_SLAVER+"@tcp("+DBHOST+":"+DBPORT+")/"+DBNAME+"?charset=utf8mb4") | |||
| // if dbConnErr != nil { | |||
| // log.Println("ERROR", "can not connect to Database, ", dbConnErr) | |||
| // time.Sleep(time.Second * 5) | |||
| // } else { | |||
| // if len(conns) > 0 { | |||
| // SLAVER_DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 | |||
| // } else { | |||
| // SLAVER_DB.SetMaxOpenConns(200) //默认值为0表示不限制 | |||
| // } | |||
| // if len(conns) > 1 { | |||
| // SLAVER_DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 | |||
| // } else { | |||
| // SLAVER_DB.SetMaxIdleConns(50) | |||
| // } | |||
| // SLAVER_DB.Ping() | |||
| // log.Println("database connected") | |||
| // SLAVER_DB.SetConnMaxLifetime(time.Minute * 2) | |||
| // break | |||
| // } | |||
| // } | |||
| // } else { | |||
| // return errors.New("db connection params errors") | |||
| // } | |||
| // return dbConnErr | |||
| } | |||
| func connectDb(dbhost, dbuser, dbpwd, dbname, dbport string, conns ...int) (*sql.DB, error) { | |||
| log.Println("database connectting...") | |||
| var dbconn *sql.DB | |||
| var dbConnErr error | |||
| if dbhost != "" && dbuser != "" && dbpwd != "" && dbport != "" { | |||
| for i := 0; i < 10; i++ { | |||
| dbconn, dbConnErr = sql.Open("mysql", dbuser+":"+dbpwd+"@tcp("+dbhost+":"+dbport+")/"+dbname+"?charset=utf8mb4") | |||
| if dbConnErr != nil { | |||
| log.Println("ERROR", "can not connect to Database, ", dbConnErr) | |||
| time.Sleep(time.Second * 5) | |||
| } else { | |||
| if len(conns) > 0 { | |||
| dbconn.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 | |||
| } else { | |||
| dbconn.SetMaxOpenConns(200) //默认值为0表示不限制 | |||
| } | |||
| if len(conns) > 1 { | |||
| dbconn.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 | |||
| } else { | |||
| dbconn.SetMaxIdleConns(50) | |||
| } | |||
| // dbconn.Ping() | |||
| // log.Println(dbconn.Stats()) | |||
| log.Println("database connected") | |||
| dbconn.SetConnMaxLifetime(time.Minute * 1) | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| return nil, errors.New("db connection params errors") | |||
| } | |||
| return dbconn, dbConnErr | |||
| } | |||
| // func CloseSlaverConn() error { | |||
| // return SLAVER_DB.Close() | |||
| // } | |||
| /** | |||
| * 检测表名 | |||
| */ | |||
| func getTableName(dbName, table string, dbtype ...string) string { | |||
| var db_type string = "mysql" | |||
| if len(dbtype) > 0 { | |||
| if dbtype[0] != "" { | |||
| db_type = dbtype[0] | |||
| } | |||
| } | |||
| var ret string | |||
| switch db_type { | |||
| case "mysql": | |||
| if strings.Contains(table, ".") { | |||
| ret = table | |||
| } | |||
| if dbName != "" { | |||
| ret = StringJoin(dbName, ".", table) | |||
| } else { | |||
| ret = table | |||
| } | |||
| case "mssql": | |||
| ret = StringJoin(dbName, ".", table) | |||
| } | |||
| return ret | |||
| } | |||
| func GetDbTableName(dbName, table string) string { | |||
| return getTableName(dbName, table) | |||
| } | |||
| func judg() []string { | |||
| return []string{"=", ">", "<", "!=", "<=", ">="} | |||
| } | |||
| @ -0,0 +1,905 @@ | |||
| package tencentdb | |||
| import ( | |||
| "database/sql" | |||
| "log" | |||
| "strconv" | |||
| "errors" | |||
| "strings" | |||
| "time" | |||
| _ "github.com/go-sql-driver/mysql" | |||
| ) | |||
| /** | |||
| * 创建数据 | |||
| */ | |||
| func Insert(dbName, table string, data map[string]string) (int64, error) { | |||
| var insertId int64 | |||
| var err error | |||
| if dbName == "" && table == "" { | |||
| return insertId, errors.New("没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(data) < 1 { | |||
| return insertId, errors.New("没有要写入的数据") | |||
| } | |||
| keyList := make([]string, len(data)) | |||
| keyStr := make([]string, len(data)) | |||
| valueList := make([]interface{}, len(data)) | |||
| var i int = 0 | |||
| for key, value := range data { | |||
| keyList[i] = key | |||
| keyStr[i] = "?" | |||
| valueList[i] = value | |||
| 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 | |||
| } else { | |||
| insertId, _ = result.LastInsertId() | |||
| time.Sleep(time.Second * 2) | |||
| return insertId, nil | |||
| } | |||
| } | |||
| /** | |||
| * 修改数据 | |||
| */ | |||
| func Update(dbName, table string, data map[string]string, where map[string]string) (int64, error) { | |||
| var rowsAffected int64 | |||
| var err error | |||
| if dbName == "" && table == "" { | |||
| return rowsAffected, errors.New("没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(data) < 1 { | |||
| return rowsAffected, errors.New("同有更新的数据") | |||
| } | |||
| if len(where) < 1 { | |||
| return rowsAffected, errors.New("没有更新条件") | |||
| } | |||
| keyList := make([]string, len(data)) | |||
| valueList := make([]interface{}, len(data), len(data)+len(where)) | |||
| whereStr := make([]string, len(where)) | |||
| var i int = 0 | |||
| empty := false | |||
| for key, value := range data { | |||
| keyList[i] = key + "=?" | |||
| valueList[i] = value | |||
| i++ | |||
| } | |||
| i = 0 | |||
| for key, value := range where { | |||
| if value == "" { | |||
| empty = true | |||
| break | |||
| } | |||
| whereStr[i] = key + "=?" | |||
| valueList = append(valueList, value) | |||
| i++ | |||
| } | |||
| if empty { | |||
| log.Println("ERROR|修改数据表", dbName, "时条件中有空数据,条件:", where, "数据:", data) | |||
| return rowsAffected, errors.New("条件中有空数据") | |||
| } | |||
| result, err := DB.Exec("update "+dbName+" set "+strings.Join(keyList, " , ")+" where "+strings.Join(whereStr, " and "), valueList...) | |||
| if err != nil { | |||
| log.Println("ERROR|修改", dbName, "数据失败,", err) | |||
| return rowsAffected, err | |||
| } else { | |||
| rowsAffected, _ = result.RowsAffected() | |||
| return rowsAffected, nil | |||
| } | |||
| } | |||
| /** | |||
| * 删除数据 | |||
| * @param count 删除数量 | |||
| */ | |||
| func Delete(dbName, table string, data map[string]string, del_count ...string) (int64, error) { | |||
| var count int64 | |||
| var err error | |||
| if dbName == "" && table == "" { | |||
| return count, errors.New("没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(data) < 1 { | |||
| return count, errors.New("没有要删除的数据") | |||
| } | |||
| keyList := make([]string, len(data)) | |||
| valueList := make([]interface{}, len(data)) | |||
| var i int = 0 | |||
| empty := false | |||
| for key, value := range data { | |||
| if value == "" { | |||
| empty = true | |||
| break | |||
| } | |||
| keyList[i] = key + "=?" | |||
| valueList[i] = value | |||
| i++ | |||
| } | |||
| if empty { | |||
| log.Println("ERROR|删除数据表", dbName, "时条件中有空数据,条件:", data) | |||
| return count, errors.New("条件中有空数据") | |||
| } | |||
| var limitStr string = "" | |||
| if len(del_count) > 0 { | |||
| limitStr = " limit " + del_count[0] | |||
| } | |||
| result, err := DB.Exec("delete from "+dbName+" where "+strings.Join(keyList, " and ")+limitStr, valueList...) | |||
| if err != nil { | |||
| log.Println("ERROR|删除", dbName, "数据失败,", err) | |||
| return count, err | |||
| } else { | |||
| count, _ = result.RowsAffected() | |||
| return count, nil | |||
| } | |||
| } | |||
| /** | |||
| * 查找一条记录 | |||
| * @param dbName 数据表名 | |||
| * @param title 查询字段名 | |||
| */ | |||
| func GetData(dbName, table string, title string, where map[string]string, limit map[string]string) (int, map[string]string, error) { | |||
| var count int = 0 | |||
| info := make(map[string]string) | |||
| if dbName == "" && table == "" { | |||
| return count, info, errors.New("没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(title) < 1 { | |||
| return count, info, errors.New("没有指定查询内容") | |||
| } | |||
| var limitStr string = "" | |||
| if limit != nil && len(limit) > 0 { | |||
| var from string = "0" //开始 | |||
| if _, ok := limit["order"]; ok { | |||
| limitStr += " order by " + limit["order"] | |||
| } | |||
| if _, ok := limit["from"]; ok { | |||
| from = limit["from"] | |||
| } | |||
| limitStr += " limit " + from + ",1" | |||
| } else { | |||
| limitStr = " limit 1" | |||
| } | |||
| if len(where) < 1 { | |||
| return count, info, errors.New("Query condition is empty") | |||
| } | |||
| keyList := make([]string, len(where)) | |||
| valueList := make([]interface{}, len(where)) | |||
| var i int = 0 | |||
| empty := false | |||
| for key, value := range where { | |||
| if value == "" { | |||
| empty = true | |||
| break | |||
| } | |||
| keyList[i] = key + " = ? " | |||
| valueList[i] = value | |||
| i++ | |||
| } | |||
| if empty { | |||
| return count, info, errors.New("Query condition is empty") | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| for queryNum < 3 { //如发生错误,继续查询3次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("SELECT "+title+" FROM "+dbName+" where "+strings.Join(keyList, " and ")+" "+limitStr, valueList...) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| log.Println("ERROR", "Query from", dbName, "failed,", err, "| SELECT "+title+" FROM "+dbName+" where "+strings.Join(keyList, " and ")+" "+limitStr) | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| defer rows.Close() | |||
| if err != nil { | |||
| return count, info, err | |||
| } | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var index string | |||
| var rowerr error | |||
| for rows.Next() { | |||
| rowerr = rows.Scan(scanArgs...) | |||
| if rowerr == nil { | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| info[index] = ToString(col) | |||
| } | |||
| } | |||
| count++ | |||
| } else { | |||
| log.Println("ERROR", "rows scan error", rowerr, dbName, keyList, valueList) | |||
| } | |||
| } | |||
| if rowerr != nil { | |||
| return count, info, rowerr | |||
| } | |||
| return count, info, nil | |||
| } | |||
| /** | |||
| * 查找一条记录 | |||
| * @param dbName 数据表名 | |||
| * @param title 查询字段名 | |||
| */ | |||
| func GetRow(dbconn *sql.DB, dbName, table_name, alias string, titles string, join [][]string, where, where_or []string, valueList []interface{}, orderby string, debug bool) (int, map[string]string, error) { | |||
| var count int = 0 | |||
| info := make(map[string]string) | |||
| if dbName == "" && table_name == "" { | |||
| return count, info, errors.New("没有数据表") | |||
| } | |||
| table := getTableName(dbName, table_name) | |||
| var sql_str, title string | |||
| if titles != "" { | |||
| title = titles | |||
| } else { | |||
| title = "*" | |||
| } | |||
| sql_str = StringJoin("/*slave*/ select ", title) | |||
| if alias != "" { | |||
| table = StringJoin(table, " as ", alias) | |||
| } | |||
| sql_str = StringJoin(sql_str, " from ", table) | |||
| if len(join) > 0 { | |||
| for _, joinitem := range join { | |||
| if len(joinitem) < 2 { | |||
| continue | |||
| } | |||
| if len(joinitem) == 3 { | |||
| sql_str = StringJoin(sql_str, " ", joinitem[2], " join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1]) | |||
| } else { //默认左连接 | |||
| sql_str = StringJoin(sql_str, " left join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1]) | |||
| } | |||
| } | |||
| } | |||
| if len(where) > 0 || len(where_or) > 0 { | |||
| sql_str = StringJoin(sql_str, " where ") | |||
| } | |||
| if len(where) > 0 { | |||
| sql_str = StringJoin(sql_str, " (", strings.Join(where, " and "), " ) ") | |||
| } | |||
| if len(where_or) > 0 { | |||
| if len(where) > 0 { | |||
| sql_str = StringJoin(sql_str, " or ", strings.Join(where_or, " or ")) | |||
| } else { | |||
| sql_str = StringJoin(sql_str, strings.Join(where_or, " or ")) | |||
| } | |||
| } | |||
| if orderby != "" { | |||
| sql_str = StringJoin(sql_str, " order by ", orderby) | |||
| } | |||
| if debug { | |||
| log.Println("query sql:", sql_str, valueList) | |||
| } | |||
| condition_len := 0 //所有条件数 | |||
| for _, ch2 := range sql_str { | |||
| if string(ch2) == "?" { | |||
| condition_len++ | |||
| } | |||
| } | |||
| if condition_len != len(valueList) { | |||
| return 0, nil, errors.New("参数错误,条件值错误") | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| sql_str = StringJoin(sql_str, " limit 1") | |||
| for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题 | |||
| rows, err = dbconn.Query(sql_str, valueList...) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| log.Println(err) | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| if err != nil { | |||
| rows.Close() | |||
| return count, info, err | |||
| } | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var index string | |||
| var rowerr error | |||
| for rows.Next() { | |||
| rowerr = rows.Scan(scanArgs...) | |||
| if rowerr == nil { | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| info[index] = ToString(col) | |||
| } | |||
| } | |||
| count++ | |||
| } else { | |||
| log.Println("ERROR", rowerr) | |||
| } | |||
| } | |||
| rows.Close() | |||
| if rowerr != nil { | |||
| return count, info, rowerr | |||
| } | |||
| return count, info, nil | |||
| } | |||
| /** | |||
| * 查找多条记录 | |||
| * @param dbName 数据表名 | |||
| * @param title 查询字段名 | |||
| */ | |||
| func FetchRows(dbconn *sql.DB, dbName, table_name, alias string, titles string, join [][]string, where, where_or []string, valueList []interface{}, orderby string, page int, page_size int, debug bool) (int, []map[string]string, error) { | |||
| var count int = 0 | |||
| list := make([]map[string]string, 0) | |||
| if dbName == "" && table_name == "" { | |||
| return count, list, errors.New("没有数据表") | |||
| } | |||
| table := getTableName(dbName, table_name) | |||
| var sql_str, title string | |||
| if titles != "" { | |||
| title = titles | |||
| } else { | |||
| title = "*" | |||
| } | |||
| sql_str = StringJoin("/*slave*/ select ", title) | |||
| if alias != "" { | |||
| table = StringJoin(table, " as ", alias) | |||
| } | |||
| sql_str = StringJoin(sql_str, " from ", table) | |||
| if len(join) > 0 { | |||
| for _, joinitem := range join { | |||
| if len(joinitem) < 2 { | |||
| continue | |||
| } | |||
| if len(joinitem) == 3 { | |||
| sql_str = StringJoin(sql_str, " ", joinitem[2], " join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1]) | |||
| } else { //默认左连接 | |||
| sql_str = StringJoin(sql_str, " left join ", getTableName(dbName, joinitem[0]), " on ", joinitem[1]) | |||
| } | |||
| } | |||
| } | |||
| if len(where) > 0 || len(where_or) > 0 { | |||
| sql_str = StringJoin(sql_str, " where ") | |||
| } | |||
| if len(where) > 0 { | |||
| sql_str = StringJoin(sql_str, " (", strings.Join(where, " and "), " ) ") | |||
| } | |||
| if len(where_or) > 0 { | |||
| if len(where) > 0 { | |||
| sql_str = StringJoin(sql_str, " or ", strings.Join(where_or, " or ")) | |||
| } else { | |||
| sql_str = StringJoin(sql_str, strings.Join(where_or, " or ")) | |||
| } | |||
| } | |||
| if orderby != "" { | |||
| sql_str = StringJoin(sql_str, " order by ", orderby) | |||
| } | |||
| if page > 0 || page_size > 0 { | |||
| if page < 1 { | |||
| page = 1 | |||
| } | |||
| if page_size < 1 { | |||
| page_size = 10 | |||
| } | |||
| from := strconv.Itoa((page - 1) * page_size) | |||
| offset := strconv.Itoa(page_size) | |||
| if from != "" && offset != "" { | |||
| sql_str = StringJoin(sql_str, " limit ", from, " , ", offset) | |||
| } | |||
| } | |||
| if debug { | |||
| log.Println("query sql:", sql_str, valueList) | |||
| } | |||
| condition_len := 0 //所有条件数 | |||
| for _, ch2 := range sql_str { | |||
| if string(ch2) == "?" { | |||
| condition_len++ | |||
| } | |||
| } | |||
| if condition_len != len(valueList) { | |||
| return 0, list, errors.New("参数错误,条件值错误") | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| for queryNum < 2 { //如发生错误,继续查询2次,防止数据库连接断开问题 | |||
| rows, err = dbconn.Query(sql_str, valueList...) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| log.Println(err) | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| if err != nil { | |||
| rows.Close() | |||
| return 0, list, err | |||
| } | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var index string | |||
| var rowerr error | |||
| var info map[string]string | |||
| for rows.Next() { | |||
| rowerr = rows.Scan(scanArgs...) | |||
| info = make(map[string]string) | |||
| if rowerr == nil { | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| info[index] = ToString(col) | |||
| } | |||
| } | |||
| count++ | |||
| } else { | |||
| log.Println("ERROR", rowerr) | |||
| } | |||
| if len(info) > 0 { | |||
| list = append(list, info) | |||
| } | |||
| } | |||
| rows.Close() | |||
| return count, list, nil | |||
| } | |||
| func GetInfo(dbName, table string, title string, where map[string]string) (map[string]string, error) { | |||
| count, info, gzErr := GetData(dbName, table, title, where, nil) | |||
| if gzErr != nil { | |||
| return info, gzErr | |||
| } else { | |||
| if count < 1 { | |||
| return info, errors.New("No data") | |||
| } | |||
| return info, nil | |||
| } | |||
| } | |||
| /** | |||
| * 查询列表 | |||
| * 2018/04/19 | |||
| */ | |||
| func GetList(dbName, table string, title string, where map[string]string, limit map[string]string) ([]map[string]string, error) { | |||
| var list []map[string]string | |||
| if dbName == "" && table == "" { | |||
| return list, errors.New("没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| var limitStr string = "" | |||
| if len(limit) > 0 { | |||
| var offset string = "0" //偏移量,个数 | |||
| var from string = "" //开始 | |||
| if _, ok := limit["order"]; ok { | |||
| limitStr += " order by " + limit["order"] | |||
| } | |||
| if _, ok := limit["offset"]; ok { | |||
| offset = limit["offset"] | |||
| } | |||
| if _, ok := limit["from"]; ok { | |||
| from = limit["from"] | |||
| } | |||
| if offset != "0" && from != "" { | |||
| limitStr += " limit " + from + "," + offset | |||
| } | |||
| } | |||
| if len(where) > 0 { | |||
| valueList := make([]interface{}, len(where)) | |||
| whereStr := make([]string, len(where)) | |||
| i := 0 | |||
| var keys []string | |||
| for key, value := range where { | |||
| key = strings.Trim(key, " ") | |||
| value = strings.Trim(value, " ") | |||
| if value == "" || key == "" { | |||
| continue | |||
| // return list, errors.New("Query condition is empty") | |||
| } | |||
| if strings.Contains(key, " ") { | |||
| //key中包含空格,判断是否不等于条件 | |||
| keys = strings.Split(key, " ") | |||
| if IsInStringArray(judg(), strings.Trim(keys[1], " ")) { | |||
| whereStr[i] = strings.Trim(keys[0], " ") + " " + strings.Trim(keys[1], " ") + " ?" | |||
| } | |||
| } else { | |||
| whereStr[i] = key + " = ?" | |||
| valueList[i] = value | |||
| } | |||
| i++ | |||
| } | |||
| if len(whereStr) == 0 || len(valueList) == 0 { | |||
| return list, errors.New("Query condition is empty") | |||
| } | |||
| for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("select "+title+" from "+dbName+" where "+strings.Join(whereStr, " and ")+" "+limitStr, valueList...) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| } else { | |||
| for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("select " + title + " from " + dbName + " " + limitStr) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| } | |||
| if err != nil { | |||
| return list, err | |||
| } | |||
| defer rows.Close() | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var record map[string]string | |||
| var index string | |||
| for rows.Next() { | |||
| //将行数据保存到record字典 | |||
| err = rows.Scan(scanArgs...) | |||
| record = make(map[string]string) | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| record[index] = ToString(col) | |||
| } | |||
| } | |||
| list = append(list, record) | |||
| } | |||
| return list, nil | |||
| } | |||
| /** | |||
| * 查询总数 | |||
| * 2018/04/19 | |||
| */ | |||
| func GetTotal(dbName, table string, args ...string) (total int) { | |||
| if dbName == "" && table == "" { | |||
| return | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| var title string = "*" | |||
| if len(args) > 0 { | |||
| title = args[0] | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("select count(" + title + ") as count from " + dbName + " limit 1") | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| if err != nil { | |||
| log.Println("ERROR|get", dbName, "total error", err) | |||
| return | |||
| } | |||
| defer rows.Close() | |||
| var count int | |||
| for rows.Next() { | |||
| //将行数据保存到record字典 | |||
| err = rows.Scan(&count) | |||
| if err != nil { | |||
| log.Println("ERROR|get", dbName, "total error", err) | |||
| } else { | |||
| total = count | |||
| } | |||
| } | |||
| return | |||
| } | |||
| /** | |||
| * 查询总数 | |||
| * 2020/06/04 | |||
| */ | |||
| func GetCount(dbName, table string, where map[string]string, args ...string) (total int) { | |||
| if dbName == "" && table == "" { | |||
| return | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| var title string = "*" | |||
| if len(title) > 0 { | |||
| title = args[0] | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| if len(where) > 0 { | |||
| valueList := make([]interface{}, len(where)) | |||
| whereStr := make([]string, len(where)) | |||
| i := 0 | |||
| var keys []string | |||
| for key, value := range where { | |||
| key = strings.Trim(key, " ") | |||
| value = strings.Trim(value, " ") | |||
| if value == "" || key == "" { | |||
| continue | |||
| // return list, errors.New("Query condition is empty") | |||
| } | |||
| if strings.Contains(key, " ") { | |||
| //key中包含空格,判断是否不等于条件 | |||
| keys = strings.Split(key, " ") | |||
| if IsInStringArray(judg(), strings.Trim(keys[1], " ")) { | |||
| whereStr[i] = strings.Trim(keys[0], " ") + " " + strings.Trim(keys[1], " ") + " ?" | |||
| } | |||
| } else { | |||
| whereStr[i] = key + " = ?" | |||
| valueList[i] = value | |||
| } | |||
| i++ | |||
| } | |||
| for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("select count("+title+") as count from "+dbName+" where "+strings.Join(whereStr, " and ")+" limit 1", valueList...) | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| } else { | |||
| for queryNum < 5 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| rows, err = DB.Query("select count(" + title + ") as count from " + dbName + " limit 1") | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| } | |||
| if err != nil { | |||
| log.Println("ERROR|get", dbName, "count error", err) | |||
| return | |||
| } | |||
| defer rows.Close() | |||
| var count int | |||
| for rows.Next() { | |||
| //将行数据保存到record字典 | |||
| err = rows.Scan(&count) | |||
| if err != nil { | |||
| log.Println("ERROR|get", dbName, "count error", err) | |||
| } else { | |||
| total = count | |||
| } | |||
| } | |||
| return | |||
| } | |||
| func DoQuery(args ...interface{}) ([]map[string]string, error) { | |||
| var list []map[string]string | |||
| if len(args) < 1 { | |||
| return list, errors.New("Query condition is empty") | |||
| } | |||
| queryStr := ToString(args[0]) | |||
| if queryStr == "" { | |||
| return list, errors.New("Query condition is empty") | |||
| } | |||
| var rows *sql.Rows | |||
| var err error | |||
| var queryNum int = 0 | |||
| for queryNum < 3 { //如发生错误,继续查询5次,防止数据库连接断开问题 | |||
| if len(args) > 1 { | |||
| rows, err = DB.Query(queryStr, args[1:]...) //strings.Join(args[1:], ",") | |||
| if err != nil { | |||
| log.Println("ERROR|DoQuery error:", err) | |||
| } | |||
| } else { | |||
| rows, err = DB.Query(queryStr) | |||
| if err != nil { | |||
| log.Println("ERROR|DoQuery error:", err) | |||
| } | |||
| } | |||
| if err == nil { | |||
| break | |||
| } else { | |||
| time.Sleep(time.Millisecond * 500) | |||
| } | |||
| queryNum++ | |||
| } | |||
| if err != nil { | |||
| return list, err | |||
| } | |||
| defer rows.Close() | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var record map[string]string | |||
| var index string | |||
| for rows.Next() { | |||
| //将行数据保存到record字典 | |||
| err = rows.Scan(scanArgs...) | |||
| record = make(map[string]string) | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| record[index] = ToString(col) | |||
| } | |||
| } | |||
| list = append(list, record) | |||
| } | |||
| return list, nil | |||
| } | |||
| @ -0,0 +1,51 @@ | |||
| package tencentdb | |||
| import ( | |||
| "log" | |||
| "testing" | |||
| ) | |||
| func Test_Connet(t *testing.T) { | |||
| //go func() { | |||
| for i := 0; i < 1; i++ { | |||
| dbhost := "localhost" | |||
| dbname := "shop" | |||
| dbusername := "tetele" | |||
| dbpassword := "fly123456" | |||
| dbport := "3306" | |||
| table := "ttl_order_product" | |||
| err := Connect(dbhost, dbusername, dbpassword, dbname, dbport) | |||
| if err != nil { | |||
| log.Println(err.Error()) | |||
| } | |||
| //_,err = new(Query).Db(dbname).Table("ttl_user").Where("id > 0").Select() | |||
| // _, err = new(Query).Db(dbname).Table("ttl_news"). | |||
| // Datas([]string{"title=?", "content=?"}). | |||
| // Values([]interface{}{"aaaaaaaaa", "bbbbbb"}).Create() | |||
| title := "op.id,op.sn,op.order_price" | |||
| alias := "op" | |||
| join := [][]string{} | |||
| join = append(join, []string{"ttl_product as p", "op.product_id=p.id"}) | |||
| where := []string{} | |||
| where_or := []string{} | |||
| valueList := []interface{}{} | |||
| orderby := "id desc" | |||
| debug := true | |||
| // count, row, err := GetRow(dbname, table, alias, title, join, where, where_or, valueList, orderby, debug) | |||
| count, row, err := FetchRows(dbname, table, alias, title, join, where, where_or, valueList, orderby, 1, 10, debug) | |||
| log.Println(count) | |||
| log.Println(row) | |||
| log.Println(err) | |||
| if err != nil { | |||
| log.Println(err.Error()) | |||
| } | |||
| } | |||
| //}() | |||
| } | |||
| @ -0,0 +1,7 @@ | |||
| module git.tetele.net/mysql/tencentdb | |||
| go 1.16 | |||
| require ( | |||
| github.com/go-sql-driver/mysql v1.5.0 | |||
| ) | |||
| @ -0,0 +1,11 @@ | |||
| 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= | |||
| 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/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/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= | |||
| 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= | |||
| golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | |||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||
| @ -0,0 +1,456 @@ | |||
| package tencentdb | |||
| import ( | |||
| "database/sql" | |||
| "errors" | |||
| "log" | |||
| "strings" | |||
| ) | |||
| /** | |||
| * 准备查询 | |||
| * return Stmt error | |||
| */ | |||
| func StmtForRead(dbName, table string, title string, where []string, limit map[string]string) (*sql.Stmt, error) { | |||
| if dbName == "" && table == "" { | |||
| return nil, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(title) < 1 { | |||
| return nil, errors.New("没有要查询内容") | |||
| } | |||
| var limitStr string = "" | |||
| if limit != nil && len(limit) > 0 { | |||
| var from, offset string = "", "" //开始 | |||
| if _, ok := limit["order"]; ok { | |||
| limitStr += " order by " + limit["order"] | |||
| } | |||
| if _, ok := limit["from"]; ok { | |||
| from = limit["from"] | |||
| } | |||
| if _, ok := limit["offset"]; ok { | |||
| offset = limit["offset"] | |||
| } | |||
| if from != "" && offset != "" { | |||
| limitStr += " limit " + from + "," + offset | |||
| } | |||
| } | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| if len(where) > 0 { | |||
| // 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) | |||
| } else { | |||
| // log.Println("SELECT " + title + " FROM " + dbName + limitStr) | |||
| stmt, err = DB.Prepare("SELECT " + title + " FROM " + dbName + limitStr) | |||
| } | |||
| return stmt, err | |||
| } | |||
| func CloseStmt(stmt *sql.Stmt) error { | |||
| return stmt.Close() | |||
| } | |||
| /** | |||
| * 执行查询列表 | |||
| * return list error | |||
| */ | |||
| func StmtForQueryList(stmt *sql.Stmt, valuelist []interface{}) ([]map[string]string, error) { | |||
| if stmt == nil { | |||
| return nil, errors.New("缺少必要参数") | |||
| } | |||
| // log.Println(valuelist...) | |||
| rows, err := stmt.Query(valuelist...) | |||
| defer stmt.Close() | |||
| if err != nil { | |||
| if stmt != nil { | |||
| stmt.Close() | |||
| } | |||
| return nil, err | |||
| } | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var list []map[string]string | |||
| var index string | |||
| var rowerr error | |||
| info := make(map[string]string) | |||
| for rows.Next() { | |||
| rowerr = rows.Scan(scanArgs...) | |||
| info = make(map[string]string) | |||
| if rowerr == nil { | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| info[index] = ToString(col) | |||
| } | |||
| } | |||
| } else { | |||
| log.Println("rows scan error", rowerr) | |||
| } | |||
| if len(info) > 0 { | |||
| list = append(list, info) | |||
| } | |||
| } | |||
| return list, nil | |||
| } | |||
| /** | |||
| * 执行查询一条数据 | |||
| * return row error | |||
| */ | |||
| func StmtForQueryRow(stmt *sql.Stmt, valuelist []interface{}) (map[string]string, error) { | |||
| if stmt == nil || len(valuelist) < 1 { | |||
| return nil, errors.New("缺少必要参数") | |||
| } | |||
| rows, err := stmt.Query(valuelist...) | |||
| defer stmt.Close() | |||
| if err != nil { | |||
| if stmt != nil { | |||
| stmt.Close() | |||
| } | |||
| return nil, err | |||
| } | |||
| columns, _ := rows.Columns() | |||
| scanArgs := make([]interface{}, len(columns)) | |||
| values := make([]interface{}, len(columns)) | |||
| for i := range values { | |||
| scanArgs[i] = &values[i] | |||
| } | |||
| var index string | |||
| var rowerr error | |||
| info := make(map[string]string) | |||
| for rows.Next() { | |||
| rowerr = rows.Scan(scanArgs...) | |||
| if rowerr == nil { | |||
| for i, col := range values { | |||
| if col != nil { | |||
| index = StrFirstToUpper(columns[i]) | |||
| info[index] = ToString(col) | |||
| } | |||
| } | |||
| } else { | |||
| log.Println("rows scan error", rowerr) | |||
| } | |||
| } | |||
| if rowerr != nil { | |||
| return info, errors.New("数据出错") | |||
| } | |||
| return info, nil | |||
| } | |||
| /** | |||
| * 准备更新 | |||
| * return Stmt error | |||
| */ | |||
| func StmtForUpdate(dbName, table string, data []string, where []string) (*sql.Stmt, error) { | |||
| if dbName == "" && table == "" { | |||
| return nil, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(where) < 1 { | |||
| return nil, errors.New("参数错误,没有更新条件") | |||
| } | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| stmt, err = DB.Prepare("update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and ")) | |||
| return stmt, err | |||
| } | |||
| /** | |||
| * 执行更新 | |||
| * return is_updated error | |||
| */ | |||
| func StmtForUpdateExec(stmt *sql.Stmt, valuelist []interface{}) (int64, error) { | |||
| res, err := stmt.Exec(valuelist...) | |||
| if err != nil { | |||
| return 0, errors.New("更新失败:" + err.Error()) | |||
| } | |||
| return res.RowsAffected() | |||
| } | |||
| /** | |||
| * 准备写入 | |||
| * return Stmt error | |||
| */ | |||
| func StmtForInsert(dbName, table string, data []string) (*sql.Stmt, error) { | |||
| if dbName == "" && table == "" { | |||
| return nil, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(data) < 1 { | |||
| return nil, errors.New("参数错误,没有要写入的数据") | |||
| } | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| stmt, err = DB.Prepare("insert into " + dbName + " set " + strings.Join(data, " , ")) | |||
| return stmt, err | |||
| } | |||
| /** | |||
| * 执行写入 | |||
| * @return lastId error | |||
| */ | |||
| func StmtForInsertExec(stmt *sql.Stmt, valuelist []interface{}) (int64, error) { | |||
| res, err := stmt.Exec(valuelist...) | |||
| if err != nil { | |||
| return 0, errors.New("创建失败:" + err.Error()) | |||
| } | |||
| return res.LastInsertId() | |||
| } | |||
| /** | |||
| * 使用db prepare方式查询列表 | |||
| * @param dbName | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * @param page 查询范围,可传两个值 pageNum,pageSize | |||
| * GZ | |||
| * 2020/05/19 | |||
| */ | |||
| func GetListByStmt(dbName string, table string, title string, where []string, valuelist []interface{}, limit map[string]string, page ...int) ([]map[string]string, error) { | |||
| if len(page) > 0 { | |||
| pageNum, pageSize := page[0], 10 | |||
| if len(page) > 1 { | |||
| pageSize = page[1] | |||
| } | |||
| limit["from"], limit["offset"] = GetPage(pageNum, pageSize) | |||
| } | |||
| stmt, err := StmtForRead(dbName, table, title, where, limit) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryList(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 使用db prepare方式查询单条数据 | |||
| * @param dbName | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * GZ | |||
| * 2020/05/19 | |||
| */ | |||
| func GetDataByStmt(dbName string, table string, title string, where []string, valuelist []interface{}, limit map[string]string) (map[string]string, error) { | |||
| stmt, err := StmtForRead(dbName, table, title, where, limit) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryRow(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 使用db prepare修改数据 | |||
| * @param dbName | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * GZ | |||
| * 2020/05/19 | |||
| */ | |||
| func UpdateByStmt(dbName string, table string, data []string, where []string, valuelist []interface{}) (int64, error) { | |||
| stmt, err := StmtForUpdate(dbName, table, data, where) | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForUpdateExec(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 使用db prepare写入数据 | |||
| * @param dbName | |||
| * @param table 表名 | |||
| * @param data 写入的字段 | |||
| * @param valuelist 写入的值 | |||
| * GZ | |||
| * 2020/08/06 | |||
| */ | |||
| func InsertByStmt(dbName string, table string, data []string, valuelist []interface{}) (int64, error) { | |||
| stmt, err := StmtForInsert(dbName, table, data) | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForInsertExec(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 自定义查询 | |||
| * return Stmt error | |||
| */ | |||
| func StmtForQuery(querysql string) (*sql.Stmt, error) { | |||
| if querysql == "" { | |||
| return nil, errors.New("参数错误,没有数据表") | |||
| } | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| stmt, err = DB.Prepare(querysql) | |||
| return stmt, err | |||
| } | |||
| /** | |||
| * 执行自定义查询 | |||
| * @return lastId error | |||
| */ | |||
| func QueryByStmt(sql string, valuelist []interface{}) ([]map[string]string, error) { | |||
| stmt, err := StmtForQuery(sql) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryList(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 联表查询 | |||
| * @param dbName | |||
| * @param tableA 表一 | |||
| * @param tableA_alias 表一别名 | |||
| * @param tableB 表二 | |||
| * @param tableB_alias 表二别名 | |||
| * @param join 联表方式 | |||
| * @param join_on 联表字段 | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * @param page 查询范围,可传两个值 pageNum,pageSize | |||
| * GZ | |||
| * 2020/11/23 | |||
| */ | |||
| func GetJoinListByStmt(dbName string, tableA, tableA_alias string, tableB, tableB_alias string, join_type, join_on string, title string, where []string, valuelist []interface{}, limit map[string]string, page ...int) ([]map[string]string, error) { | |||
| if len(page) > 0 { | |||
| pageNum, pageSize := page[0], 10 | |||
| if len(page) > 1 { | |||
| pageSize = page[1] | |||
| } | |||
| limit["from"], limit["offset"] = GetPage(pageNum, pageSize) | |||
| } | |||
| if tableA_alias != "" { | |||
| tableA = StringJoin(dbName, ".", tableA, " as ", tableA_alias) | |||
| } | |||
| if tableB_alias != "" { | |||
| tableB = StringJoin(dbName, ".", tableB, " as ", tableB_alias) | |||
| } | |||
| table := StringJoin(tableA, " ", join_type, " join ", tableB, " on ", join_on) | |||
| stmt, err := StmtForRead(dbName, table, title, where, limit) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryList(stmt, valuelist) | |||
| } | |||
| /** | |||
| * 左联表查询 | |||
| * @param dbName | |||
| * @param tableA 表一 | |||
| * @param tableB 表二 | |||
| * @param join_on 联表字段 | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * @param page 查询范围,可传两个值 pageNum,pageSize | |||
| * GZ | |||
| * 2021/1/27 | |||
| */ | |||
| func LeftJoinListByStmt(dbName string, tableA, tableB string, join_on string, title string, where []string, valuelist []interface{}, limit map[string]string, page ...int) ([]map[string]string, error) { | |||
| if len(page) > 0 { | |||
| pageNum, pageSize := page[0], 10 | |||
| if len(page) > 1 { | |||
| pageSize = page[1] | |||
| } | |||
| limit["from"], limit["offset"] = GetPage(pageNum, pageSize) | |||
| } | |||
| tableA = getTableName(dbName, tableA) | |||
| tableB = getTableName(dbName, tableB) | |||
| table := StringJoin(tableA, " left join ", tableB, " on ", join_on) | |||
| stmt, err := StmtForRead(dbName, table, title, where, limit) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryList(stmt, valuelist) | |||
| } | |||
| @ -0,0 +1,21 @@ | |||
| package tencentdb | |||
| import ( | |||
| "testing" | |||
| ) | |||
| func Test_StmtForExec(t *testing.T) { | |||
| Connect("127.0.0.1", "root", "123456", "tetele_empty", "3306") | |||
| stmt, err := StmtForUpdate("dev_tetele_net", "ttl_xshop_order", []string{"user_id = ?", "pay_time = pay_time+1"}, []string{"id=1"}) | |||
| if err != nil { | |||
| t.Error(err) | |||
| } | |||
| defer stmt.Close() | |||
| ret, err := StmtForUpdateExec(stmt, []interface{}{"1"}) | |||
| t.Log(ret) | |||
| t.Log(err) | |||
| } | |||
| @ -0,0 +1,167 @@ | |||
| package tencentdb | |||
| import ( | |||
| "fmt" | |||
| "log" | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| /* | |||
| * 连接多个字符串 | |||
| * 2019/05/05 | |||
| */ | |||
| func StringJoin(s ...string) string { | |||
| var build strings.Builder | |||
| if len(s) > 0 { | |||
| for _, v := range s { | |||
| build.WriteString(v) | |||
| } | |||
| } | |||
| return build.String() | |||
| } | |||
| /** | |||
| * 字符串转大驼峰 ios_bbbbbbbb -> IosBbbbbbbbb | |||
| */ | |||
| func StrFirstToUpper(str string) string { | |||
| str = strings.ReplaceAll(str, "`", "") | |||
| temp := strings.Split(str, "_") | |||
| var upperStr string | |||
| for y := 0; y < len(temp); y++ { | |||
| vv := []rune(temp[y]) | |||
| for i := 0; i < len(vv); i++ { | |||
| if i == 0 { | |||
| vv[i] -= 32 | |||
| upperStr += string(vv[i]) | |||
| } else { | |||
| upperStr += string(vv[i]) | |||
| } | |||
| } | |||
| } | |||
| return upperStr | |||
| } | |||
| func ToString(v interface{}) string { | |||
| var value string | |||
| switch v.(type) { | |||
| case string: | |||
| value = v.(string) | |||
| case int: | |||
| value = strconv.Itoa(v.(int)) | |||
| case float64: | |||
| value = strconv.FormatFloat(v.(float64), 'f', 2, 64) | |||
| case float32: | |||
| value = strconv.FormatFloat(float64(v.(float32)), 'f', 2, 64) | |||
| case int64: | |||
| value = strconv.FormatInt(v.(int64), 10) | |||
| case []uint8: | |||
| value = string(v.([]uint8)) | |||
| // case []byte: | |||
| // value = string(v.([]byte)) | |||
| case interface{}: | |||
| value = v.(string) | |||
| case nil: | |||
| value = "" | |||
| default: | |||
| log.Println("参数值类型错误", v, "not in string|int|float64|interface|int64") | |||
| } | |||
| return strings.Trim(value, " ") | |||
| } | |||
| /** | |||
| * 是否存在在字符切片中 | |||
| */ | |||
| func IsInStringArray(arr []string, str string) bool { | |||
| var isIn bool = false | |||
| length := len(arr) | |||
| if length < 1 { | |||
| return false | |||
| } | |||
| for _, item := range arr { | |||
| if item == str { | |||
| isIn = true | |||
| break | |||
| } | |||
| } | |||
| return isIn | |||
| } | |||
| func ToInt(inter interface{}) int { | |||
| var value int | |||
| switch inter.(type) { | |||
| case string: | |||
| value, _ = strconv.Atoi(inter.(string)) | |||
| case int: | |||
| value = inter.(int) | |||
| case int64: | |||
| value = int(inter.(int64)) | |||
| case float64: | |||
| value, _ = strconv.Atoi(fmt.Sprintf("%1.0f", inter)) | |||
| case nil: | |||
| value = 0 | |||
| case interface{}: | |||
| value = inter.(int) | |||
| default: | |||
| log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64") | |||
| } | |||
| return value | |||
| } | |||
| func ToInt64(inter interface{}) int64 { | |||
| var value int64 | |||
| switch inter.(type) { | |||
| case string: | |||
| value, _ = strconv.ParseInt(inter.(string), 10, 64) | |||
| case int: | |||
| value = int64(inter.(int)) | |||
| case int64: | |||
| value = inter.(int64) | |||
| case float64: | |||
| value_int, _ := strconv.Atoi(fmt.Sprintf("%1.0f", inter)) | |||
| value = int64(value_int) | |||
| case nil: | |||
| value = 0 | |||
| case interface{}: | |||
| if _, ok := inter.(int64); !ok { | |||
| value = inter.(int64) | |||
| } | |||
| default: | |||
| log.Println("参数值类型错误", inter, "not in string|int|float64|interface|int64") | |||
| } | |||
| return value | |||
| } | |||
| /** | |||
| * 根据第几页计算从第几行开始 | |||
| * @param pageNum 第几页 | |||
| * @param pageSize 每页几行 | |||
| * @return from,offset 开始行数,偏移量 | |||
| * 2020/05/15 | |||
| * gz | |||
| */ | |||
| func GetPage(pageNum, pageSize interface{}) (string, string) { | |||
| var from string | |||
| var offset int = ToInt(pageSize) | |||
| var pageNumInt, pageSizeInt int = ToInt(pageNum), ToInt(pageSize) | |||
| if pageNumInt < 1 { | |||
| pageNumInt = 1 | |||
| } | |||
| if pageSizeInt < 1 { | |||
| offset = 10 | |||
| pageSizeInt = 10 | |||
| } | |||
| from = ToString((pageNumInt - 1) * pageSizeInt) | |||
| return from, ToString(offset) | |||
| } | |||
| @ -0,0 +1,301 @@ | |||
| /** | |||
| * DB transaction | |||
| */ | |||
| package tencentdb | |||
| import ( | |||
| "database/sql" | |||
| "errors" | |||
| "log" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| /** | |||
| * 创建数据 | |||
| */ | |||
| func TxInsert(tx *sql.Tx, dbname, table string, data map[string]string) (int64, error) { | |||
| var insertId int64 | |||
| var err error | |||
| if dbname == "" && table == "" { | |||
| return 0, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName := getTableName(dbname, table) | |||
| if len(data) < 1 { | |||
| return 0, errors.New("参数错误,没有要写入的数据") | |||
| } | |||
| keyList := make([]string, len(data)) | |||
| keyStr := make([]string, len(data)) | |||
| valueList := make([]interface{}, len(data)) | |||
| var i int = 0 | |||
| for key, value := range data { | |||
| keyList[i] = key | |||
| keyStr[i] = "?" | |||
| valueList[i] = value | |||
| 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 | |||
| } else { | |||
| insertId, _ = result.LastInsertId() | |||
| time.Sleep(time.Second * 2) | |||
| return insertId, nil | |||
| } | |||
| } | |||
| /** | |||
| * 准备写入 | |||
| * return Stmt error | |||
| */ | |||
| func TxPreInsert(tx *sql.Tx, dbname, table string, data map[string]interface{}) (int64, error) { | |||
| if dbname == "" && table == "" { | |||
| return 0, errors.New("params error,no db or table") | |||
| } | |||
| dbName := getTableName(dbname, table) | |||
| if len(data) < 1 { | |||
| return 0, errors.New("params error,no data to insert") | |||
| } | |||
| var err error | |||
| var stmt *sql.Stmt | |||
| var field []string = make([]string, len(data)) | |||
| var valuelist []interface{} = make([]interface{}, len(data)) | |||
| var i int = 0 | |||
| for key, item := range data { | |||
| field[i] = key + "=?" | |||
| valuelist[i] = item | |||
| i++ | |||
| } | |||
| 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()) | |||
| } | |||
| insertId, _ := result.LastInsertId() | |||
| return insertId, nil | |||
| } | |||
| /** | |||
| * 修改数据 | |||
| */ | |||
| func TxUpdate(tx *sql.Tx, dbname, table string, data map[string]string, where map[string]string) (int64, error) { | |||
| var rowsAffected int64 | |||
| var err error | |||
| if dbname == "" && table == "" { | |||
| return rowsAffected, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName := getTableName(dbname, table) | |||
| if len(data) < 1 { | |||
| return rowsAffected, errors.New("参数错误,没有要写入的数据") | |||
| } | |||
| if len(where) < 1 { | |||
| return rowsAffected, errors.New("参数错误,没有修改条件") | |||
| } | |||
| keyList := make([]string, len(data)) | |||
| valueList := make([]interface{}, len(data), len(data)+len(where)) | |||
| whereStr := make([]string, len(where)) | |||
| var i int = 0 | |||
| empty := false | |||
| for key, value := range data { | |||
| keyList[i] = key + "=?" | |||
| valueList[i] = value | |||
| i++ | |||
| } | |||
| i = 0 | |||
| for key, value := range where { | |||
| if value == "" { | |||
| empty = true | |||
| break | |||
| } | |||
| whereStr[i] = key + "=?" | |||
| valueList = append(valueList, value) | |||
| i++ | |||
| } | |||
| if empty { | |||
| log.Println("ERROR", "update", dbName, "error, params empty") | |||
| return rowsAffected, errors.New("params empty") | |||
| } | |||
| result, err := tx.Exec("update "+dbName+" set "+strings.Join(keyList, " , ")+" where "+strings.Join(whereStr, " and "), valueList...) | |||
| if err != nil { | |||
| log.Println("ERROR", "update", dbName, "error:", err) | |||
| return rowsAffected, err | |||
| } else { | |||
| rowsAffected, _ = result.RowsAffected() | |||
| return rowsAffected, nil | |||
| } | |||
| } | |||
| /** | |||
| * 准备更新 | |||
| * return Stmt error | |||
| */ | |||
| func TxPreUpdate(tx *sql.Tx, dbname, table string, data []string, where []string, valuelist []interface{}) (int64, error) { | |||
| if dbname == "" && table == "" { | |||
| return 0, errors.New("params error,no db or table") | |||
| } | |||
| dbName := getTableName(dbname, table) | |||
| if len(where) < 1 { | |||
| return 0, errors.New("params error, no data for update") | |||
| } | |||
| var err error | |||
| var stmt *sql.Stmt | |||
| sql := "update " + dbName + " set " + strings.Join(data, " , ") + " where " + strings.Join(where, " and ") | |||
| stmt, err = tx.Prepare(sql) | |||
| if err != nil { | |||
| log.Println("update prepare error:", sql, err) | |||
| return 0, errors.New("update prepare error:" + err.Error()) | |||
| } | |||
| res, err := stmt.Exec(valuelist...) | |||
| if err != nil { | |||
| log.Println("update exec error:", sql, valuelist, err) | |||
| return 0, errors.New("update exec error:" + err.Error()) | |||
| } | |||
| return res.RowsAffected() | |||
| } | |||
| /** | |||
| * 删除数据 | |||
| * @param count 删除数量 | |||
| */ | |||
| func TxDelete(tx *sql.Tx, dbname, table string, where map[string]string, del_count ...string) (int64, error) { | |||
| var count int64 | |||
| var err error | |||
| if dbname == "" && table == "" { | |||
| return count, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName := getTableName(dbname, table) | |||
| if len(where) < 1 { | |||
| return count, errors.New("参数错误,没有删除条件") | |||
| } | |||
| keyList := make([]string, len(where)) | |||
| valueList := make([]interface{}, len(where)) | |||
| var i int = 0 | |||
| empty := false | |||
| for key, value := range where { | |||
| if value == "" { | |||
| empty = true | |||
| break | |||
| } | |||
| keyList[i] = key + "=?" | |||
| valueList[i] = value | |||
| i++ | |||
| } | |||
| if empty { | |||
| log.Println("ERROR", "delete from", dbName, "error, where:", where) | |||
| return count, errors.New("params empty") | |||
| } | |||
| var limitStr string = "" | |||
| if len(del_count) > 0 { | |||
| limitStr = " limit " + del_count[0] | |||
| } | |||
| result, err := tx.Exec("delete from "+dbName+" where "+strings.Join(keyList, " and ")+limitStr, valueList...) | |||
| if err != nil { | |||
| log.Println("ERROR", "delete from", dbName, "error:", err) | |||
| return count, err | |||
| } else { | |||
| count, _ = result.RowsAffected() | |||
| return count, nil | |||
| } | |||
| } | |||
| /** | |||
| * 准备查询 | |||
| * return Stmt error | |||
| */ | |||
| func TxForRead(tx *sql.Tx, dbName, table string, title string, where []string) (*sql.Stmt, error) { | |||
| if dbName == "" && table == "" { | |||
| return nil, errors.New("参数错误,没有数据表") | |||
| } | |||
| dbName = getTableName(dbName, table) | |||
| if len(title) < 1 { | |||
| return nil, errors.New("没有要查询内容") | |||
| } | |||
| var stmt *sql.Stmt | |||
| var err error | |||
| if len(where) > 0 { | |||
| // 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") | |||
| } else { | |||
| // log.Println("SELECT " + title + " FROM " + dbName + " FOR UPDATE") | |||
| stmt, err = tx.Prepare("SELECT " + title + " FROM " + dbName + " FOR UPDATE") | |||
| } | |||
| return stmt, err | |||
| } | |||
| /** | |||
| * 使用db prepare方式查询单条数据 | |||
| * @param dbName | |||
| * @param title 查询的字段名 | |||
| * @param where 查询条件 | |||
| * @param valuelist 查询的条件值 | |||
| * @param limit 查询排序 | |||
| * GZ | |||
| * 2020/05/19 | |||
| */ | |||
| func TxGetData(tx *sql.Tx, dbName string, table string, title string, where []string, valuelist []interface{}) (map[string]string, error) { | |||
| stmt, err := TxForRead(tx, dbName, table, title, where) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer stmt.Close() | |||
| return StmtForQueryRow(stmt, valuelist) | |||
| } | |||
| @ -0,0 +1,451 @@ | |||
| package tencentdb | |||
| /** | |||
| * 事务操作 | |||
| */ | |||
| import ( | |||
| "database/sql" | |||
| "errors" | |||
| "log" | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| 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 | |||
| 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 = StringJoin("select ", title) | |||
| if this.alias != "" { | |||
| table = StringJoin(table, " as ", this.alias) | |||
| } | |||
| sql = StringJoin(sql, " from ", table) | |||
| if len(this.join) > 0 { | |||
| for _, joinitem := range this.join { | |||
| if len(joinitem) < 2 { | |||
| continue | |||
| } | |||
| if len(joinitem) == 3 { | |||
| sql = StringJoin(sql, " ", joinitem[2], " join ", getTableName(this.dbname, joinitem[0]), " on ", joinitem[1]) | |||
| } else { //默认左连接 | |||
| sql = StringJoin(sql, " left join ", getTableName(this.dbname, joinitem[0]), " on ", joinitem[1]) | |||
| } | |||
| } | |||
| } | |||
| if len(this.where) > 0 || len(this.where_or) > 0 { | |||
| sql = StringJoin(sql, " where ") | |||
| } | |||
| if len(this.where) > 0 { | |||
| sql = StringJoin(sql, " (", strings.Join(this.where, " and "), " ) ") | |||
| } | |||
| if len(this.where_or) > 0 { | |||
| if len(this.where) > 0 { | |||
| sql = StringJoin(sql, " or ", strings.Join(this.where_or, " or ")) | |||
| } else { | |||
| sql = StringJoin(sql, strings.Join(this.where_or, " or ")) | |||
| } | |||
| } | |||
| if this.orderby != "" { | |||
| sql = 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 = 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 = StringJoin("update ", dbName, " set ", strings.Join(this.data, " , ")) | |||
| sql = 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 = 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 = StringJoin("delete from ", dbName, " where ", strings.Join(this.where, " and ")) | |||
| if this.page_size > 0 { | |||
| sql = 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) { | |||
| this.page = 1 | |||
| this.page_size = 1 | |||
| 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() | |||
| } | |||