Skip to content

Commit 33b2b2c

Browse files
committed
fix tx support and only keep the optimized api
1 parent a9c99fd commit 33b2b2c

4 files changed

Lines changed: 40 additions & 92 deletions

File tree

README.md

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,13 @@ mdb := db.GetCache("master")
6363
mdb := db.GetCache("master")
6464
// or mdb = <sql.Tx>
6565
66-
// row := mdb.QueryRow("SELECT * ...")
67-
row := qsql.QueryRow(mdb, "SELECT * ...")
66+
row := mdb.QueryRow("SELECT * ...")
6867
// ...
6968
70-
// rows, err := mdb.Query("SELECT * ...")
71-
rows, err := qsql.Query(mdb, "SELECT * ...")
69+
rows, err := mdb.Query("SELECT * ...")
7270
// ...
7371
74-
// result, err := mdb.Exec("UPDATE ...")
75-
result, err := qsql.Exec(mdb, "UPDATE ...")
72+
result, err := mdb.Exec("UPDATE ...")
7673
// ...
7774
```
7875

@@ -209,30 +206,21 @@ if err != nil {
209206
}
210207
```
211208

212-
## Make a MultiTx
209+
## Make a lazy tx commit
213210
``` text
214-
multiTx := []*qsql.MultiTx{}
215-
multiTx = append(multiTx, qsql.NewMultiTx(
216-
"UPDATE testing SET name = ? WHERE id = ?",
217-
id,
218-
))
219-
multiTx = append(multiTx, qsql.NewMultiTx(
220-
"UPDATE testing SET name = ? WHERE id = ?",
221-
id,
222-
))
223-
224-
// do exec multi tx
211+
// commit the tx
225212
mdb := db.GetCache("master")
226213
tx, err := mdb.Begin()
227214
if err != nil{
228215
// ...
229216
}
230-
if err := qsql.ExecMutlTx(tx, multiTx); err != nil {
231-
qsql.Rollback(tx)
232-
// ...
217+
fn := func() error {
218+
if err := tx.Exec("UPDATE testing SET name = ? WHERE id = ?", id); err != nil{
219+
return err
220+
}
221+
return nil
233222
}
234-
if err := tx.Commit(); err != nil {
235-
qsql.Rollback(tx)
223+
if err := qsql.Commit(tx, fn); err != nil {
236224
// ...
237225
}
238226
```

api.go

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,23 @@ func Close(closer io.Closer) {
8585

8686
// A lazy function to rollback the *sql.Tx
8787
func Rollback(tx *sql.Tx) {
88-
err := tx.Rollback()
89-
90-
// roll back error is a serious error
91-
if err != nil {
88+
if err := tx.Rollback(); err != nil {
89+
// roll back error is a serious error
9290
log.Error(errors.As(err))
9391
}
9492
}
9593

96-
// A way implement the sql.Exec
97-
func Exec(db Execer, querySql string, args ...interface{}) (sql.Result, error) {
98-
return db.Exec(querySql, args...)
99-
}
100-
func ExecContext(db Execer, ctx context.Context, querySql string, args ...interface{}) (sql.Result, error) {
101-
return db.ExecContext(ctx, querySql, args...)
102-
}
103-
104-
// A way to ran multiply tx
105-
func ExecMultiTx(tx *sql.Tx, mTx []*MultiTx) error {
106-
return execMultiTx(tx, context.TODO(), mTx)
107-
}
108-
func ExecMultiTxContext(tx *sql.Tx, ctx context.Context, mTx []*MultiTx) error {
109-
return execMultiTx(tx, ctx, mTx)
94+
// A lazy function to commit the *sql.Tx
95+
// if will auto commit when the function is nil error, or do a rollback and return the function error.
96+
func Commit(tx *sql.Tx, fn func() error) error {
97+
if err := fn(); err != nil {
98+
Rollback(tx)
99+
return err
100+
}
101+
if err := tx.Commit(); err != nil {
102+
return err
103+
}
104+
return nil
110105
}
111106

112107
// Reflect one db data to the struct. the struct tag format like `db:"field_title"`, reference to: http://github.com/jmoiron/sqlx
@@ -118,22 +113,6 @@ func InsertStructContext(exec Execer, ctx context.Context, obj interface{}, tbNa
118113
return insertStruct(exec, ctx, obj, tbName, drvName...)
119114
}
120115

121-
// A sql.Query implements
122-
func Query(db Queryer, querySql string, args ...interface{}) (*sql.Rows, error) {
123-
return db.Query(querySql, args...)
124-
}
125-
func QueryContext(db Queryer, ctx context.Context, querySql string, args ...interface{}) (*sql.Rows, error) {
126-
return db.QueryContext(ctx, querySql, args...)
127-
}
128-
129-
// A sql.QueryRow implements
130-
func QueryRow(db Queryer, querySql string, args ...interface{}) *sql.Row {
131-
return db.QueryRow(querySql, args...)
132-
}
133-
func QueryRowContext(db Queryer, ctx context.Context, querySql string, args ...interface{}) *sql.Row {
134-
return db.QueryRowContext(ctx, querySql, args...)
135-
}
136-
137116
// Relect the sql.Rows to a struct.
138117
func ScanStruct(rows Rows, obj interface{}) error {
139118
return scanStruct(rows, obj)

example/qsql.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func main() {
1919
defer qsql.Close(mdb)
2020

2121
// create table
22-
if _, err := qsql.Exec(mdb,
22+
if _, err := mdb.Exec(
2323
`CREATE TABLE user (
2424
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
2525
"created_at" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -30,7 +30,7 @@ func main() {
3030
}
3131

3232
// std insert
33-
if _, err := qsql.Exec(mdb, "INSERT INTO user(username,passwd)VALUES(?,?)", "t1", "t1"); err != nil {
33+
if _, err := mdb.Exec("INSERT INTO user(username,passwd)VALUES(?,?)", "t1", "t1"); err != nil {
3434
panic(err)
3535
}
3636

@@ -46,7 +46,7 @@ func main() {
4646
// std query
4747
var id int64
4848
var username, passwd string
49-
if err := qsql.QueryRow(mdb, "SELECT id, username, passwd FROM user WHERE username=?", "t1").Scan(&id, &username, &passwd); err != nil {
49+
if err := mdb.QueryRow("SELECT id, username, passwd FROM user WHERE username=?", "t1").Scan(&id, &username, &passwd); err != nil {
5050
panic(err)
5151
}
5252
if username != "t1" && passwd != "t1" {
@@ -124,24 +124,23 @@ func main() {
124124
if err != nil {
125125
panic(err)
126126
}
127-
txUsers := []TestingUser{
128-
{UserName: "t3", Passwd: "t3"},
129-
{UserName: "t4", Passwd: "t4"},
130-
}
131-
for _, u := range txUsers {
132-
if _, err := qsql.InsertStruct(tx, &u, "user"); err != nil {
133-
println(errors.As(err))
134-
qsql.Rollback(tx)
135-
return
127+
if err := qsql.Commit(tx, func() error {
128+
txUsers := []TestingUser{
129+
{UserName: "t3", Passwd: "t3"},
130+
{UserName: "t4", Passwd: "t4"},
136131
}
137-
}
138-
if err := tx.Commit(); err != nil {
139-
println(errors.As(err))
140-
qsql.Rollback(tx)
141-
return
132+
for _, u := range txUsers {
133+
if _, err := qsql.InsertStruct(tx, &u, "user"); err != nil {
134+
return errors.As(err)
135+
}
136+
}
137+
return nil
138+
}); err != nil {
139+
panic(err)
142140
}
143141

144142
// excute for stmt
143+
// TODO: more stmt optimization
145144
stmt, err := mdb.Prepare("SELECT COUNT(*) FROM user WHERE username=?")
146145
count := 0
147146
if err := stmt.QueryRow("t3").Scan(&count); err != nil {

qsql.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ import (
1010
"github.com/jmoiron/sqlx/reflectx"
1111
)
1212

13-
type MultiTx struct {
14-
Query string
15-
Args []interface{}
16-
}
17-
18-
func NewMultiTx(query string, args ...interface{}) *MultiTx {
19-
return &MultiTx{query, args}
20-
}
21-
2213
const (
2314
addObjSql = "INSERT INTO %s (%s) VALUES (%s);"
2415
)
@@ -73,15 +64,6 @@ func insertStruct(exec Execer, ctx context.Context, obj interface{}, tbName stri
7364
return result, nil
7465
}
7566

76-
func execMultiTx(tx *sql.Tx, ctx context.Context, mTx []*MultiTx) error {
77-
for _, mt := range mTx {
78-
if _, err := tx.ExecContext(ctx, mt.Query, mt.Args...); err != nil {
79-
return errors.As(err)
80-
}
81-
}
82-
return nil
83-
}
84-
8567
// fieldsByName fills a values interface with fields from the passed value based
8668
// on the traversals in int. If ptrs is true, return addresses instead of values.
8769
// We write this instead of using FieldsByName to save allocations and map lookups

0 commit comments

Comments
 (0)