@@ -31,8 +31,36 @@ type TestingT interface {
31
31
Failed () bool
32
32
}
33
33
34
+ const defaultPostgresURL = "postgresql://postgres:postgres@localhost:32260/postgres?sslmode=disable"
35
+
34
36
func NewWithIsolatedDatabase (t TestingT ) * Postgres {
35
- return newPostgres (t ).cloneFromReference ()
37
+ return newPostgres (t , defaultPostgresURL ).cloneFromReference ()
38
+ }
39
+
40
+ func NewWithTransactionalCleanup (t TestingT ) interface {
41
+ ExecContext (ctx context.Context , query string , args ... any ) (sql.Result , error )
42
+ QueryRowContext (ctx context.Context , query string , args ... any ) * sql.Row
43
+ } {
44
+ // databaseName a separate database is used for transactional cleanup.
45
+ const databaseName = "transaction"
46
+
47
+ postgres := newPostgres (t , defaultPostgresURL )
48
+ postgres = postgres .replaceDBName (databaseName )
49
+
50
+ ctx , done := context .WithCancel (context .Background ())
51
+ t .Cleanup (done )
52
+
53
+ tx , err := postgres .DB ().BeginTx (ctx , & sql.TxOptions {
54
+ Isolation : sql .LevelRepeatableRead ,
55
+ ReadOnly : false ,
56
+ })
57
+ require .NoError (t , err )
58
+
59
+ t .Cleanup (func () {
60
+ require .NoError (t , tx .Rollback ())
61
+ })
62
+
63
+ return tx
36
64
}
37
65
38
66
type Postgres struct {
@@ -45,10 +73,10 @@ type Postgres struct {
45
73
sqlDBOnce sync.Once
46
74
}
47
75
48
- func newPostgres (t TestingT ) * Postgres {
76
+ func newPostgres (t TestingT , defaultPostgresURL string ) * Postgres {
49
77
urlStr := os .Getenv ("TESTING_DB_URL" )
50
78
if urlStr == "" {
51
- urlStr = "postgresql://postgres:postgres@localhost:32260/postgres?sslmode=disable"
79
+ urlStr = defaultPostgresURL
52
80
53
81
const format = "env TESTING_DB_URL is empty, used default value: %s"
54
82
@@ -105,11 +133,22 @@ func (p *Postgres) cloneFromReference() *Postgres {
105
133
require .NoError (p .t , err )
106
134
})
107
135
136
+ return p .replaceDBName (newDBName )
137
+ }
138
+
139
+ func (p * Postgres ) replaceDBName (newDBName string ) * Postgres {
140
+ o := p .clone ()
141
+ o .url = replaceDBName (p .t , p .URL (), newDBName )
142
+
143
+ return o
144
+ }
145
+
146
+ func (p * Postgres ) clone () * Postgres {
108
147
return & Postgres {
109
148
t : p .t ,
110
149
111
- url : replaceDBName ( p . t , p . URL (), newDBName ) ,
112
- ref : newDBName ,
150
+ url : p . url ,
151
+ ref : p . ref ,
113
152
}
114
153
}
115
154
@@ -176,7 +215,7 @@ func open(t TestingT, dataSourceURL string) *sql.DB {
176
215
177
216
// Automatically close connection after the test is completed.
178
217
t .Cleanup (func () {
179
- db .Close ()
218
+ require . NoError ( t , db .Close () )
180
219
})
181
220
182
221
return db
0 commit comments