Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: pgxpool, added more example using pgx driver #680

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 48 additions & 0 deletions examples/go-pgx-migration/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module go-pgx-migration

go 1.21.1

require (
github.com/jackc/pgx/v5 v5.5.1
github.com/ory/dockertest/v3 v3.10.0
github.com/pressly/goose/v3 v3.17.0
)

require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/containerd/continuity v0.4.3 // indirect
github.com/docker/cli v24.0.7+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.10 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sethvargo/go-retry v0.2.4 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
224 changes: 224 additions & 0 deletions examples/go-pgx-migration/go.sum

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions examples/go-pgx-migration/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"database/sql"
"embed"
"errors"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/pressly/goose/v3"
)

type Migration struct {
db *sql.DB
}

//go:embed migrations/*.sql
var embedMigrations embed.FS

func NewMigration(pool *pgxpool.Pool) (*Migration, error) {
if pool == nil {
return &Migration{}, errors.New("pool is nil")
}

goose.SetBaseFS(embedMigrations)

if err := goose.SetDialect("postgres"); err != nil {
return &Migration{}, err
}

cp := pool.Config().ConnConfig.ConnString()
db, err := sql.Open("pgx/v5", cp)
if err != nil {
return &Migration{}, err
}

return &Migration{db: db}, nil
}

func (m *Migration) Up() error {
if err := goose.Up(m.db, "migrations"); err != nil {
return err
}
return nil
}

func (m *Migration) Down() error {
if err := goose.Down(m.db, "migrations"); err != nil {
return err
}
return nil
}
91 changes: 91 additions & 0 deletions examples/go-pgx-migration/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package main_test

import (
"context"
"fmt"
main "go-pgx-migration"
"log"
"os"
"testing"
"time"

"github.com/jackc/pgx/v5/pgxpool"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)

var pool *pgxpool.Pool

func TestMain(m *testing.M) {
dockerPool, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("Could not connect to docker %v", err)
}

resource, err := dockerPool.RunWithOptions(&dockertest.RunOptions{
Repository: "postgres",
Tag: "16",
Env: []string{
"POSTGRES_PASSWORD=secret",
"POSTGRES_USER=postgres",
"POSTGRES_DB=postgres",
"listen_addresses = '*'",
},
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{
Name: "no",
}
})
if err != nil {
log.Fatalf("Could not start resource %v", err)
}

hostAndPort := resource.GetHostPort("5432/tcp")
databaseUrl := fmt.Sprintf("postgres://postgres:secret@%s/postgres?sslmode=disable", hostAndPort)

if err := resource.Expire(120); err != nil {
log.Fatalf("Could not set expire %v", err)
} // Tell docker to hard kill the container in 120 seconds

dockerPool.MaxWait = 120 * time.Second
if err := dockerPool.Retry(func() error {
var err error
pool, err = pgxpool.New(context.Background(), databaseUrl)
if err != nil {
return err
}
return pool.Ping(context.Background())
}); err != nil {
log.Fatalf("Could not connect to docker %v", err)
}
code := m.Run()

if err := dockerPool.Purge(resource); err != nil {
// You should handle this error
log.Fatalf("Could not purge resource: %v", err)
}

os.Exit(code)
}

func TestMigration(t *testing.T) {
migration, err := main.NewMigration(pool)
if err != nil {
t.Errorf("NewMigration failed %v", err)
}

t.Run("Up Migration", func(t *testing.T) {
err = migration.Up()
if err != nil {
t.Errorf("Migration failed %v", err)
}
})
t.Run("Down Migration", func(t *testing.T) {
err = migration.Down()
if err != nil {
t.Errorf("Migration failed %v", err)
}
})
}
14 changes: 14 additions & 0 deletions examples/go-pgx-migration/migrations/00001_create_users_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- +goose Up
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT,
name TEXT,
surname TEXT
);

INSERT INTO users VALUES
(0, 'root', '', ''),
(1, 'vojtechvitek', 'Vojtech', 'Vitek');

-- +goose Down
DROP TABLE users;
22 changes: 22 additions & 0 deletions examples/go-pgx-migration/migrations/00002_rename_root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package migrations

import (
"context"
"database/sql"

"github.com/pressly/goose/v3"
)

func init() {
goose.AddMigrationContext(Up00002, Down00002)
}

func Up00002(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, "UPDATE users SET username='admin' WHERE username='root';")
return err
}

func Down00002(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, "UPDATE users SET username='root' WHERE username='admin';")
return err
}
44 changes: 44 additions & 0 deletions examples/go-pgx-migration/migrations/00003_add_user_no_tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package migrations

import (
"context"
"database/sql"
"errors"

"github.com/pressly/goose/v3"
)

func init() {
goose.AddMigrationNoTxContext(Up00003, Down00003)
}

func Up00003(ctx context.Context, db *sql.DB) error {
id, err := getUserID(db, "jamesbond")
if err != nil {
return err
}
if id == 0 {
query := "INSERT INTO users (username, name, surname) VALUES ($1, $2, $3)"
if _, err := db.ExecContext(ctx, query, "jamesbond", "James", "Bond"); err != nil {
return err
}
}
return nil
}

func getUserID(db *sql.DB, username string) (int, error) {
var id int
err := db.QueryRow("SELECT id FROM users WHERE username = $1", username).Scan(&id)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return 0, err
}
return id, nil
}

func Down00003(ctx context.Context, db *sql.DB) error {
query := "DELETE FROM users WHERE username = $1"
if _, err := db.ExecContext(ctx, query, "jamesbond"); err != nil {
return err
}
return nil
}
7 changes: 7 additions & 0 deletions examples/go-pgx-migration/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# STACKS
- Postgres
- Go
- [Pgx/v5](https://github.com/jackc/pgx/tree/v5.5.1)
- [Pgx/v5/stdlib](https://github.com/jackc/pgx/blob/master/stdlib/sql.go#L69)
- [Pgx/v5/pgxpool](https://github.com/jackc/pgx/blob/master/pgxpool/pool.go#L1)
- [Dockertest](https://github.com/ory/dockertest)