Skip to content

Commit 2e2ea5c

Browse files
committedJan 4, 2018
fix(): transactions were not really working
Signed-off-by: Geoffrey Bauduin <geoffrey.bauduin@corp.ovh.com>
1 parent 2173053 commit 2e2ea5c

6 files changed

+137
-28
lines changed
 

‎db.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ type DB interface {
2222

2323
type db struct {
2424
zesty.DB
25+
dbmap *gorp.DbMap
2526
system DMS
2627
executorHook ExecutorHook
2728
}
2829

29-
func (d db) System() DMS {
30+
func (d *db) System() DMS {
3031
return d.system
3132
}
3233

33-
func (d db) ExecutorHook() ExecutorHook {
34+
func (d *db) ExecutorHook() ExecutorHook {
3435
if d.executorHook == nil {
3536
return &DefaultExecutorHook{}
3637
}
@@ -56,6 +57,15 @@ type DatabaseConfiguration struct {
5657
ExecutorHook ExecutorHook
5758
}
5859

60+
// GetDB returns a database object from its name
61+
func GetDB(name string) (DB, error) {
62+
db, ok := registry[name]
63+
if !ok {
64+
return nil, errors.NotFoundf("database %s", name)
65+
}
66+
return db, nil
67+
}
68+
5969
// RegisterDB creates a new database with configuration
6070
func RegisterDB(config *DatabaseConfiguration) error {
6171
dblock.Lock()
@@ -86,7 +96,7 @@ func RegisterDB(config *DatabaseConfiguration) error {
8696
return err
8797
}
8898

89-
registry[config.Name] = db{
99+
registry[config.Name] = &db{
90100
DB: dbHandler,
91101
system: config.System,
92102
executorHook: config.ExecutorHook,

‎db_test.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ func TestDb_System(t *testing.T) {
7979
AutoCreateTables: true,
8080
})
8181
assert.Nil(t, err)
82-
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
82+
_, err = yaorm.NewDBProvider(context.TODO(), "test")
8383
assert.Nil(t, err)
84-
assert.Equal(t, yaorm.DatabaseSqlite3, dbp.DB().(yaorm.DB).System())
84+
db, err := yaorm.GetDB("test")
85+
assert.Nil(t, err)
86+
assert.Equal(t, yaorm.DatabaseSqlite3, db.System())
8587
}
8688

8789
func TestDb_ExecutorHook(t *testing.T) {
@@ -96,9 +98,11 @@ func TestDb_ExecutorHook(t *testing.T) {
9698
AutoCreateTables: true,
9799
})
98100
assert.Nil(t, err)
99-
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
101+
_, err = yaorm.NewDBProvider(context.TODO(), "test")
102+
assert.Nil(t, err)
103+
db, err := yaorm.GetDB("test")
100104
assert.Nil(t, err)
101-
inst := dbp.DB().(yaorm.DB).ExecutorHook()
105+
inst := db.ExecutorHook()
102106
assert.NotNil(t, inst)
103107
assert.IsType(t, inst, &yaorm.DefaultExecutorHook{})
104108
}
@@ -126,9 +130,11 @@ func TestDb_ExecutorHook_Custom(t *testing.T) {
126130
ExecutorHook: customExecutorHook{},
127131
})
128132
assert.Nil(t, err)
129-
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
133+
_, err = yaorm.NewDBProvider(context.TODO(), "test")
134+
assert.Nil(t, err)
135+
db, err := yaorm.GetDB("test")
130136
assert.Nil(t, err)
131-
inst := dbp.DB().(yaorm.DB).ExecutorHook()
137+
inst := db.ExecutorHook()
132138
assert.NotNil(t, inst)
133139
assert.IsType(t, inst, &customExecutorHook{})
134140
}

‎dbprovider.go

+11-6
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@ func NewDBProvider(ctx context.Context, name string) (DBProvider, error) {
4646

4747
// DB returns a SQL Executor interface
4848
func (dbp *dbprovider) DB() gorp.SqlExecutor {
49-
db := registry[dbp.name]
50-
return &SqlExecutor{DB: db, ctx: dbp.Context(), dbp: dbp}
49+
dbRetrieved := dbp.getDb()
50+
dbUsed := dbp.DBProvider.DB()
51+
return &SqlExecutor{
52+
SqlExecutor: dbUsed,
53+
db: dbRetrieved,
54+
ctx: dbp.Context(),
55+
dbp: dbp,
56+
}
5157
}
5258

5359
// EscapeValue escapes the value sent according to the dialect
@@ -70,10 +76,9 @@ func (dbp *dbprovider) getDb() DB {
7076
}
7177

7278
func (dbp *dbprovider) getDialect() gorp.Dialect {
73-
v := tools.GetNonPtrValue(dbp.DB())
74-
dbField := tools.GetNonPtrValue(v.FieldByName("DB").Interface()).FieldByName("DB")
75-
realValue := tools.GetNonPtrValue(dbField.Interface())
76-
field := realValue.FieldByName("DbMap")
79+
v := tools.GetNonPtrValue(dbp.getDb())
80+
dbField := tools.GetNonPtrValue(v.FieldByName("DB").Interface())
81+
field := dbField.FieldByName("DbMap")
7782
s := field.Interface().(*gorp.DbMap)
7883
return s.Dialect
7984
}

‎dbprovider_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package yaorm_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/geoffreybauduin/yaorm"
8+
"github.com/geoffreybauduin/yaorm/testdata"
9+
"github.com/geoffreybauduin/yaorm/yaormfilter"
10+
"github.com/juju/errors"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestDbprovider_Tx(t *testing.T) {
15+
killDb, err := testdata.SetupTestDatabase("test")
16+
defer killDb()
17+
assert.Nil(t, err)
18+
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
19+
assert.Nil(t, err)
20+
err = dbp.Tx()
21+
assert.Nil(t, err)
22+
m := &testdata.Category{Name: "category"}
23+
m.SetDBP(dbp)
24+
assert.Equal(t, int64(0), m.ID)
25+
err = yaorm.GenericInsert(m)
26+
assert.Nil(t, err)
27+
dbp2, err := yaorm.NewDBProvider(context.TODO(), "test")
28+
assert.Nil(t, err)
29+
30+
// does not exist outside of tx
31+
_, err = yaorm.GenericSelectOne(dbp2, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
32+
assert.NotNil(t, err)
33+
assert.True(t, errors.IsNotFound(err))
34+
35+
// exists in tx
36+
_, err = yaorm.GenericSelectOne(dbp, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
37+
assert.Nil(t, err)
38+
39+
err = dbp.Commit()
40+
assert.Nil(t, err)
41+
42+
// now it exists outside of tx
43+
_, err = yaorm.GenericSelectOne(dbp2, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
44+
assert.Nil(t, err)
45+
}
46+
47+
func TestDbprovider_Rollback(t *testing.T) {
48+
killDb, err := testdata.SetupTestDatabase("test")
49+
defer killDb()
50+
assert.Nil(t, err)
51+
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
52+
assert.Nil(t, err)
53+
err = dbp.Tx()
54+
assert.Nil(t, err)
55+
m := &testdata.Category{Name: "category"}
56+
m.SetDBP(dbp)
57+
assert.Equal(t, int64(0), m.ID)
58+
err = yaorm.GenericInsert(m)
59+
assert.Nil(t, err)
60+
dbp2, err := yaorm.NewDBProvider(context.TODO(), "test")
61+
assert.Nil(t, err)
62+
63+
// does not exist outside of tx
64+
_, err = yaorm.GenericSelectOne(dbp2, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
65+
assert.NotNil(t, err)
66+
assert.True(t, errors.IsNotFound(err))
67+
68+
// exists in tx
69+
_, err = yaorm.GenericSelectOne(dbp, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
70+
assert.Nil(t, err)
71+
72+
err = dbp.Rollback()
73+
assert.Nil(t, err)
74+
75+
// still does not exist outside of tx
76+
_, err = yaorm.GenericSelectOne(dbp2, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
77+
assert.NotNil(t, err)
78+
assert.True(t, errors.IsNotFound(err))
79+
80+
// inside old tx it does not exist either
81+
_, err = yaorm.GenericSelectOne(dbp, testdata.NewCategoryFilter().ID(yaormfilter.Equals(m.ID)))
82+
assert.NotNil(t, err)
83+
assert.True(t, errors.IsNotFound(err))
84+
}

‎requestbuilder.go

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"reflect"
66

7-
87
"github.com/geoffreybauduin/yaorm/_vendor/github.com/lann/squirrel"
98
"github.com/geoffreybauduin/yaorm/tools"
109
)

‎sqlexecutor.go

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package yaorm
22

3-
import "context"
3+
import (
4+
"context"
5+
6+
"github.com/go-gorp/gorp"
7+
)
48

59
type SqlExecutor struct {
6-
DB
10+
gorp.SqlExecutor
11+
db DB
712
ctx context.Context
813
dbp DBProvider
914
}
1015

1116
func (e *SqlExecutor) SelectOne(holder interface{}, query string, args ...interface{}) error {
12-
hook := e.ExecutorHook()
17+
hook := e.db.ExecutorHook()
1318
hook.BeforeSelectOne(e.ctx, query, args...)
14-
err := e.DB.SelectOne(holder, query, args...)
19+
err := e.SqlExecutor.SelectOne(holder, query, args...)
1520
hook.AfterSelectOne(e.ctx, query, args...)
1621
return err
1722
}
@@ -22,15 +27,15 @@ type queryArgs struct {
2227
}
2328

2429
func (e *SqlExecutor) Select(i interface{}, query string, args ...interface{}) ([]interface{}, error) {
25-
hook := e.ExecutorHook()
30+
hook := e.db.ExecutorHook()
2631
hook.BeforeSelect(e.ctx, query, args...)
27-
v, err := e.DB.Select(i, query, args...)
32+
v, err := e.SqlExecutor.Select(i, query, args...)
2833
hook.AfterSelect(e.ctx, query, args...)
2934
return v, err
3035
}
3136

3237
func (e *SqlExecutor) Insert(list ...interface{}) error {
33-
hook := e.ExecutorHook()
38+
hook := e.db.ExecutorHook()
3439
for _, item := range list {
3540
var qArg queryArgs
3641
builder, err := buildInsert(e.dbp, item.(Model))
@@ -42,7 +47,7 @@ func (e *SqlExecutor) Insert(list ...interface{}) error {
4247
return err
4348
}
4449
hook.BeforeInsert(e.ctx, qArg.query, qArg.args...)
45-
err = e.DB.Insert(item)
50+
err = e.SqlExecutor.Insert(item)
4651
if err != nil {
4752
return err
4853
}
@@ -52,7 +57,7 @@ func (e *SqlExecutor) Insert(list ...interface{}) error {
5257
}
5358

5459
func (e *SqlExecutor) Update(list ...interface{}) (int64, error) {
55-
hook := e.ExecutorHook()
60+
hook := e.db.ExecutorHook()
5661
var rv int64
5762
for _, item := range list {
5863
var qArg queryArgs
@@ -65,7 +70,7 @@ func (e *SqlExecutor) Update(list ...interface{}) (int64, error) {
6570
return rv, err
6671
}
6772
hook.BeforeUpdate(e.ctx, qArg.query, qArg.args...)
68-
v, err := e.DB.Update(item)
73+
v, err := e.SqlExecutor.Update(item)
6974
if err != nil {
7075
return rv, err
7176
}
@@ -76,7 +81,7 @@ func (e *SqlExecutor) Update(list ...interface{}) (int64, error) {
7681
}
7782

7883
func (e *SqlExecutor) Delete(list ...interface{}) (int64, error) {
79-
hook := e.ExecutorHook()
84+
hook := e.db.ExecutorHook()
8085
var rv int64
8186
for _, item := range list {
8287
var qArg queryArgs
@@ -89,7 +94,7 @@ func (e *SqlExecutor) Delete(list ...interface{}) (int64, error) {
8994
return rv, err
9095
}
9196
hook.BeforeDelete(e.ctx, qArg.query, qArg.args...)
92-
v, err := e.DB.Delete(item)
97+
v, err := e.SqlExecutor.Delete(item)
9398
if err != nil {
9499
return rv, err
95100
}

0 commit comments

Comments
 (0)
Please sign in to comment.