Skip to content

Commit af43ce3

Browse files
committed
Remove almost useless builder method and use struct directly
1 parent 5534a2f commit af43ce3

File tree

2 files changed

+65
-86
lines changed

2 files changed

+65
-86
lines changed

README.md

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,12 @@ package main
2727

2828
import (
2929
"context"
30-
"flag"
31-
"os"
3230
"testing"
33-
"time"
3431

3532
ptg "github.com/olomix/go-test-pg"
3633
)
3734

38-
var dbpool ptg.Pgpool
39-
40-
func TestMain(m *testing.M) {
41-
var dbUri = flag.String(
42-
"db-uri",
43-
"postgres://localhost/postgres?sslmode=disable",
44-
"uri of postgres database",
45-
)
46-
var schemaFile = flag.String(
47-
"schema",
48-
"../schema.sql",
49-
"file with database schema",
50-
)
51-
flag.Parse()
52-
53-
dbpool = ptg.NewPool(*dbUri, *schemaFile, "my-project")
54-
os.Exit(m.Run())
55-
}
35+
var dbpool = &ptg.Pgpool{SchemaFile: "../schema.sql"}
5636

5737
func TestX(t *testing.T) {
5838
dbPool, dbClear := dbpool.WithEmpty(t)
@@ -68,3 +48,14 @@ func TestX(t *testing.T) {
6848
t.Log(dbName)
6949
}
7050
```
51+
52+
Connection to database configured using standard PostgreSQL environment
53+
variable https://www.postgresql.org/docs/11/libpq-envars.html. User needs
54+
permissions to create databases.
55+
56+
If you want to skip all tests, you need to set Skip field in Pgpool struct
57+
to false.
58+
59+
```go
60+
var dbpool = &ptg.Pgpool{Skip: true}
61+
```

database.go

Lines changed: 53 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,24 @@ type Fixture struct {
2525
Params []interface{}
2626
}
2727

28-
type Pgpool interface {
29-
// WithFixtures creates database from template database, and initializes it
30-
// with fixtures from `fixtures` array
31-
WithFixtures(t testing.TB, fixtures []Fixture) (*pgxpool.Pool, func())
32-
// WithSQLs creates database from template database, and initializes it
33-
// with fixtures from `sqls` array
34-
WithSQLs(t testing.TB, sqls []string) (*pgxpool.Pool, func())
35-
// WithEmpty creates empty database from template database, that was
36-
// created from `schema` file.
37-
WithEmpty(t testing.TB) (*pgxpool.Pool, func())
28+
type Pgpool struct {
29+
// BaseName is the prefix of template and temporary databases.
30+
// Default is dbtestpg.
31+
BaseName string
32+
// Name of schema file. Required. Tests would fail if not set.
33+
SchemaFile string // schema file name
34+
// If true, skip all database tests.
35+
Skip bool
36+
37+
m sync.RWMutex
38+
err error
39+
tmpl string
40+
rnd *rand.Rand
3841
}
3942

40-
type pgpool struct {
41-
m sync.RWMutex
42-
err error
43-
uri string
44-
baseName string
45-
schema string // schema file name
46-
tmpl string
47-
rnd *rand.Rand
48-
}
49-
50-
func (p *pgpool) WithFixtures(
43+
// WithFixtures creates database from template database, and initializes it
44+
// with fixtures from `fixtures` array
45+
func (p *Pgpool) WithFixtures(
5146
t testing.TB,
5247
fixtures []Fixture,
5348
) (*pgxpool.Pool, func()) {
@@ -66,7 +61,9 @@ func (p *pgpool) WithFixtures(
6661
return pool, clean
6762
}
6863

69-
func (p *pgpool) WithSQLs(t testing.TB, sqls []string) (*pgxpool.Pool, func()) {
64+
// WithSQLs creates database from template database, and initializes it
65+
// with fixtures from `sqls` array
66+
func (p *Pgpool) WithSQLs(t testing.TB, sqls []string) (*pgxpool.Pool, func()) {
7067
pool, clean := p.WithEmpty(t)
7168
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
7269
defer cancel()
@@ -82,11 +79,13 @@ func (p *pgpool) WithSQLs(t testing.TB, sqls []string) (*pgxpool.Pool, func()) {
8279
return pool, clean
8380
}
8481

85-
func (p *pgpool) getTmpl(t testing.TB) string {
86-
if p.uri == "" {
87-
t.Skip("database uri is not set")
88-
}
82+
func (p *Pgpool) getTmpl(t testing.TB) string {
8983
t.Helper()
84+
85+
if p.Skip {
86+
t.Skip("Skip database tests")
87+
}
88+
9089
p.m.RLock()
9190
err := p.err
9291
tmpl := p.tmpl
@@ -100,6 +99,7 @@ func (p *pgpool) getTmpl(t testing.TB) string {
10099
return tmpl
101100
}
102101
p.m.Lock()
102+
p.rnd = rand.New(rand.NewSource(time.Now().UnixNano() + int64(os.Getpid())))
103103
p.tmpl, p.err = p.createTemplateDB()
104104
err = p.err
105105
p.m.Unlock()
@@ -111,14 +111,18 @@ func (p *pgpool) getTmpl(t testing.TB) string {
111111
return p.tmpl
112112
}
113113

114-
func (p *pgpool) createRndDB(t testing.TB) (*pgxpool.Pool, string) {
114+
func (p *Pgpool) createRndDB(t testing.TB) (*pgxpool.Pool, string) {
115115
tmpl := p.getTmpl(t)
116116
dbName := fmt.Sprintf("%v_%v", tmpl, p.rnd.Int31())
117+
117118
err := p.createDB(dbName, tmpl)
119+
if err != nil {
120+
t.Fatal(err)
121+
}
118122

119-
cfg, err := pgxpool.ParseConfig(p.uri)
123+
cfg, err := pgxpool.ParseConfig("")
120124
if err != nil {
121-
_ = dropDB(p.uri, dbName)
125+
_ = dropDB(dbName)
122126
t.Fatal(err)
123127
}
124128
cfg.ConnConfig.Database = dbName
@@ -128,19 +132,19 @@ func (p *pgpool) createRndDB(t testing.TB) (*pgxpool.Pool, string) {
128132

129133
pool, err := pgxpool.ConnectConfig(ctx, cfg)
130134
if err != nil {
131-
_ = dropDB(p.uri, dbName)
135+
_ = dropDB(dbName)
132136
t.Fatal()
133137
}
134138

135139
return pool, dbName
136140
}
137141

138142
func withNewConnection(
139-
uri, dbName string,
143+
dbName string,
140144
fn func(context.Context, *pgx.Conn) error,
141145
) (err error) {
142146
var cfg *pgx.ConnConfig
143-
cfg, err = pgx.ParseConfig(uri)
147+
cfg, err = pgx.ParseConfig("")
144148
if err != nil {
145149
return errors.WithStack(err)
146150
}
@@ -175,17 +179,19 @@ func withNewConnection(
175179
return err
176180
}
177181

178-
func dropDB(uri, dbName string) error {
182+
func dropDB(dbName string) error {
179183
return withNewConnection(
180-
uri, "",
184+
"",
181185
func(ctx context.Context, conn *pgx.Conn) error {
182186
_, err := conn.Exec(ctx, "DROP DATABASE "+quote(dbName))
183187
return errors.WithStack(err)
184188
},
185189
)
186190
}
187191

188-
func (p *pgpool) WithEmpty(t testing.TB) (*pgxpool.Pool, func()) {
192+
// WithEmpty creates empty database from template database, that was
193+
// created from `schema` file.
194+
func (p *Pgpool) WithEmpty(t testing.TB) (*pgxpool.Pool, func()) {
189195
pool, dbName := p.createRndDB(t)
190196
return pool, func() {
191197
acquiredConns := pool.Stat().AcquiredConns()
@@ -196,40 +202,43 @@ func (p *pgpool) WithEmpty(t testing.TB) (*pgxpool.Pool, func()) {
196202
)
197203
}
198204
pool.Close()
199-
err := dropDB(p.uri, dbName)
205+
err := dropDB(dbName)
200206
if err != nil {
201207
t.Errorf("Can't drop DB %v: %v", dbName, err)
202208
}
203209
}
204210
}
205211

206-
func (p *pgpool) createDB(name, tmplName string) error {
212+
func (p *Pgpool) createDB(name, tmplName string) error {
207213
query := `CREATE DATABASE ` + quote(name)
208214
if tmplName != "" {
209215
query += ` WITH TEMPLATE ` + quote(tmplName)
210216
}
211217

212218
return withNewConnection(
213-
p.uri, "",
219+
"",
214220
func(ctx context.Context, conn *pgx.Conn) error {
215221
_, err := conn.Exec(ctx, query)
216222
return errors.WithStack(err)
217223
},
218224
)
219225
}
220226

221-
func (p *pgpool) createTemplateDB() (string, error) {
222-
schemaSql, err := ioutil.ReadFile(p.schema)
227+
func (p *Pgpool) createTemplateDB() (string, error) {
228+
if p.SchemaFile == "" {
229+
return "", errors.New("SchemaFile is empty")
230+
}
231+
schemaSql, err := ioutil.ReadFile(p.SchemaFile)
223232
if err != nil {
224233
return "", errors.WithStack(err)
225234
}
226235
checksum := md5.Sum(schemaSql)
227236
schemaHex := hex.EncodeToString(checksum[:])
228-
tmpl := fmt.Sprintf("%v_%v", p.baseName, schemaHex)
237+
tmpl := fmt.Sprintf("%v_%v", p.BaseName, schemaHex)
229238

230239
var dbExists bool
231240
err = withNewConnection(
232-
p.uri, "",
241+
"",
233242
func(ctx context.Context, conn *pgx.Conn) error {
234243
query := `
235244
SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = $1)
@@ -254,15 +263,15 @@ SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = $1)
254263
}
255264

256265
err = withNewConnection(
257-
p.uri, tmpl,
266+
tmpl,
258267
func(ctx context.Context, conn *pgx.Conn) error {
259268
_, err = conn.Exec(ctx, string(schemaSql))
260269
return errors.WithStack(err)
261270
},
262271
)
263272

264273
if err != nil {
265-
_ = dropDB(p.uri, tmpl)
274+
_ = dropDB(tmpl)
266275
return "", err
267276
}
268277

@@ -272,24 +281,3 @@ SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = $1)
272281
func quote(name string) string {
273282
return pgx.Identifier{name}.Sanitize()
274283
}
275-
276-
// NewPool create new Pgpool interface. It won't connect to database
277-
// until first reuse. `schema` file must exists and be valid SQL script.
278-
func NewPool(dbUri, schema, baseName string) Pgpool {
279-
if dbUri != "" {
280-
if baseName == "" {
281-
panic("baseName is required if database uri is set")
282-
}
283-
if schema == "" {
284-
panic("schema file name is required if database uri is set")
285-
}
286-
}
287-
return &pgpool{
288-
uri: dbUri,
289-
baseName: baseName,
290-
schema: schema,
291-
rnd: rand.New(
292-
rand.NewSource(time.Now().UnixNano() + int64(os.Getpid())),
293-
),
294-
}
295-
}

0 commit comments

Comments
 (0)