Skip to content

Commit

Permalink
Add adapters and remove upperdb
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenetriguba committed Mar 10, 2024
1 parent 4769c07 commit 57689df
Show file tree
Hide file tree
Showing 20 changed files with 359 additions and 249 deletions.
5 changes: 2 additions & 3 deletions .env.mysql
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
DB_PORT=4002

BOLT_DB_CONN_DBNAME=test_db
BOLT_DB_CONN_HOST=localhost:4002
BOLT_DB_CONN_HOST=localhost
BOLT_DB_CONN_PORT=4002
BOLT_DB_CONN_USER=test_user
BOLT_DB_CONN_PASSWORD=testpassword
BOLT_DB_CONN_DRIVER=mysql
5 changes: 2 additions & 3 deletions .env.postgresql
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
DB_PORT=4001

BOLT_DB_CONN_DBNAME=test_db
BOLT_DB_CONN_HOST=localhost:4001
BOLT_DB_CONN_HOST=localhost
BOLT_DB_CONN_PORT=4001
BOLT_DB_CONN_USER=test_user
BOLT_DB_CONN_PASSWORD=testpassword
BOLT_DB_CONN_DRIVER=postgresql
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ $ touch bolt.toml
```toml
[connection]
host = "localhost"
port = 5432
user = "bolt_user"
password = "bolt_password"
dbname = "bolt_tutorial_db"
Expand Down Expand Up @@ -275,10 +276,10 @@ version_style = "timestamp"
# required.
[connection]
# The host to use to connect to your database.
# If you need to use a particular port, use <host>:<port>.
# For example: localhost:5432. Otherwise, whatever port is
# the default for the database driver will be used.
host =
# The port to use to connect to your database.
# Note: This should be an integer.
port =
# The user to use to connect to your database.
user =
# The password to use to connect to your database.
Expand All @@ -297,6 +298,7 @@ All configuration file settings have corresponding environment variables.
- `BOLT_MIGRATIONS_DIR_PATH`
- `BOLT_MIGRATIONS_VERSION_STYLE`
- `BOLT_DB_CONN_HOST`
- `BOLT_DB_CONN_PORT`
- `BOLT_DB_CONN_USER`
- `BOLT_DB_CONN_PASSWORD`
- `BOLT_DB_CONN_DBNAME`
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
image: mysql:8.3
container_name: bolt_mysql_db
ports:
- "${DB_PORT:?err}:3306"
- "${BOLT_DB_CONN_PORT:?err}:3306"
environment:
- MYSQL_DATABASE=${BOLT_DB_CONN_DBNAME:?err}
- MYSQL_USER=${BOLT_DB_CONN_USER:?err}
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.postgresql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
image: postgres:16.1-alpine3.19
container_name: bolt_postgres_db
ports:
- "${DB_PORT:?err}:5432"
- "${BOLT_DB_CONN_PORT:?err}:5432"
environment:
- POSTGRES_DB=${BOLT_DB_CONN_DBNAME:?err}
- POSTGRES_USER=${BOLT_DB_CONN_USER:?err}
Expand Down
13 changes: 5 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,22 @@ go 1.21.6
require (
github.com/BurntSushi/toml v1.3.2
github.com/eugenetriguba/checkmate v0.3.2
github.com/go-sql-driver/mysql v1.8.0
github.com/google/subcommands v1.2.0
github.com/jackc/pgx/v4 v4.18.3
github.com/kelseyhightower/envconfig v1.4.0
github.com/upper/db/v4 v4.7.0
)

require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/go-sql-driver/mysql v1.8.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.3 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgtype v1.14.2 // indirect
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/segmentio/fasthash v1.0.3 // indirect
golang.org/x/crypto v0.21.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
golang.org/x/crypto v0.20.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
133 changes: 6 additions & 127 deletions go.sum

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions internal/bolttest/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (

func NewTestDB(t *testing.T) storage.DB {
connectionConfig := NewTestConnectionConfig()
testdb, err := storage.DBConnect(connectionConfig)
testdb, err := storage.NewDB(connectionConfig)
assert.Nil(t, err)
t.Cleanup(func() {
DropTable(t, testdb, "bolt_migrations")
assert.Nil(t, testdb.Session.Close())
assert.Nil(t, testdb.Close())
})
return testdb
}
Expand All @@ -26,12 +26,13 @@ func NewTestConnectionConfig() configloader.ConnectionConfig {
Driver: os.Getenv("BOLT_DB_CONN_DRIVER"),
DBName: os.Getenv("BOLT_DB_CONN_DBNAME"),
Host: os.Getenv("BOLT_DB_CONN_HOST"),
Port: os.Getenv("BOLT_DB_CONN_PORT"),
User: os.Getenv("BOLT_DB_CONN_USER"),
Password: os.Getenv("BOLT_DB_CONN_PASSWORD"),
}
}

func DropTable(t *testing.T, testdb storage.DB, tableName string) {
_, err := testdb.Session.SQL().Exec(fmt.Sprintf(`DROP TABLE IF EXISTS %s;`, tableName))
_, err := testdb.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s;", tableName))
assert.Nil(t, err)
}
4 changes: 2 additions & 2 deletions internal/commands/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ func (cmd *DownCmd) Execute(
return subcommands.ExitFailure
}

db, err := storage.DBConnect(cfg.Connection)
db, err := storage.NewDB(cfg.Connection)
if err != nil {
consoleOutputter.Error(fmt.Errorf("unable to connect to database: %w", err))
return subcommands.ExitFailure
}
defer db.Session.Close()
defer db.Close()

migrationDBRepo, err := repositories.NewMigrationDBRepo(db)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ func (m *StatusCmd) Execute(
return subcommands.ExitFailure
}

db, err := storage.DBConnect(cfg.Connection)
db, err := storage.NewDB(cfg.Connection)
if err != nil {
consoleOutputter.Error(fmt.Errorf("unable to connect to database: %w", err))
return subcommands.ExitFailure
}
defer db.Session.Close()
defer db.Close()

migrationDBRepo, err := repositories.NewMigrationDBRepo(db)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ func (cmd *UpCmd) Execute(
return subcommands.ExitFailure
}

db, err := storage.DBConnect(cfg.Connection)
db, err := storage.NewDB(cfg.Connection)
if err != nil {
consoleOutputter.Error(fmt.Errorf("unable to connect to database: %w", err))
return subcommands.ExitFailure
}
defer db.Session.Close()
defer db.Close()

migrationDBRepo, err := repositories.NewMigrationDBRepo(db)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions internal/configloader/configloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type MigrationsConfig struct {

type ConnectionConfig struct {
Host string `toml:"host" envconfig:"BOLT_DB_CONN_HOST"`
Port string `toml:"port" envconfig:"BOLT_DB_CONN_PORT"`
User string `toml:"user" envconfig:"BOLT_DB_CONN_USER"`
Password string `toml:"password" envconfig:"BOLT_DB_CONN_PASSWORD"`
DBName string `toml:"dbname" envconfig:"BOLT_DB_CONN_DBNAME"`
Expand Down
6 changes: 6 additions & 0 deletions internal/configloader/configloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func TestNewConfigWithInvalidVersionStyle(t *testing.T) {

func TestNewConfigFindsFileAndPopulatesConfigStruct(t *testing.T) {
bolttest.UnsetEnv(t, "BOLT_DB_CONN_HOST")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_PORT")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_USER")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_PASSWORD")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_DBNAME")
Expand All @@ -49,6 +50,7 @@ func TestNewConfigFindsFileAndPopulatesConfigStruct(t *testing.T) {
},
Connection: configloader.ConnectionConfig{
Host: "testhost",
Port: "1234",
User: "testuser",
Password: "testpassword",
DBName: "testdb",
Expand All @@ -73,6 +75,7 @@ func TestNewConfigCanBeOverridenByEnvVars(t *testing.T) {
},
Connection: configloader.ConnectionConfig{
Host: "testhost",
Port: "1234",
User: "testuser",
Password: "testpassword",
DBName: "testdb",
Expand All @@ -88,6 +91,7 @@ func TestNewConfigCanBeOverridenByEnvVars(t *testing.T) {
},
Connection: configloader.ConnectionConfig{
Host: "envtesthost",
Port: "4321",
User: "envtestuser",
Password: "envtestpassword",
DBName: "envtestdb",
Expand All @@ -97,6 +101,7 @@ func TestNewConfigCanBeOverridenByEnvVars(t *testing.T) {
t.Setenv("BOLT_MIGRATIONS_VERSION_STYLE", string(envCfg.Migrations.VersionStyle))
t.Setenv("BOLT_MIGRATIONS_DIR_PATH", envCfg.Migrations.DirectoryPath)
t.Setenv("BOLT_DB_CONN_HOST", envCfg.Connection.Host)
t.Setenv("BOLT_DB_CONN_PORT", envCfg.Connection.Port)
t.Setenv("BOLT_DB_CONN_USER", envCfg.Connection.User)
t.Setenv("BOLT_DB_CONN_PASSWORD", envCfg.Connection.Password)
t.Setenv("BOLT_DB_CONN_DBNAME", envCfg.Connection.DBName)
Expand All @@ -109,6 +114,7 @@ func TestNewConfigCanBeOverridenByEnvVars(t *testing.T) {

func TestNewConfigSearchesParentDirectories(t *testing.T) {
bolttest.UnsetEnv(t, "BOLT_DB_CONN_HOST")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_PORT")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_USER")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_PASSWORD")
bolttest.UnsetEnv(t, "BOLT_DB_CONN_DBNAME")
Expand Down
36 changes: 16 additions & 20 deletions internal/repositories/migration_db_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/eugenetriguba/bolt/internal/models"
"github.com/eugenetriguba/bolt/internal/storage"
"github.com/upper/db/v4"
)

type MigrationDBRepo interface {
Expand All @@ -29,7 +28,7 @@ type migrationDBRepo struct {
// operates on exists. If it is unable to create or confirm
// the table exists, an error is returned.
func NewMigrationDBRepo(db storage.DB) (MigrationDBRepo, error) {
_, err := db.Session.SQL().Exec(`
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS bolt_migrations(
version CHARACTER(14) PRIMARY KEY NOT NULL
);
Expand All @@ -49,7 +48,7 @@ func NewMigrationDBRepo(db storage.DB) (MigrationDBRepo, error) {
// will be ones that have been applied, and their message
// will always be an empty string.
func (mr migrationDBRepo) List() (map[string]*models.Migration, error) {
rows, err := mr.db.Session.SQL().Select("version").From("bolt_migrations").Query()
rows, err := mr.db.Query("SELECT version FROM bolt_migrations;")
if err != nil {
return nil, fmt.Errorf(
"unable to execute query to select versions from "+
Expand Down Expand Up @@ -89,12 +88,9 @@ func (mr migrationDBRepo) List() (map[string]*models.Migration, error) {
// when the version might be applied, but there was an error.
// Check err first before looking at whether the version is applied.
func (mr migrationDBRepo) IsApplied(version string) (bool, error) {
row, err := mr.db.Session.SQL().Select(1).From("bolt_migrations").Where("version = ?", version).QueryRow()
if err != nil {
return false, fmt.Errorf("unable to execute query to check if version exists in bolt_migrations: %w", err)
}
var scanResult int
err = row.Scan(&scanResult)
err := mr.db.QueryRow("SELECT 1 FROM bolt_migrations WHERE version = ?", version).
Scan(&scanResult)
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
Expand All @@ -116,7 +112,7 @@ func (mr migrationDBRepo) Apply(
upgradeScript string,
migration *models.Migration,
) error {
err := applyMigration(mr.db.Session, upgradeScript, *migration)
err := applyMigration(mr.db, upgradeScript, *migration)
if err != nil {
return err
}
Expand All @@ -131,8 +127,8 @@ func (mr migrationDBRepo) ApplyWithTx(
upgradeScript string,
migration *models.Migration,
) error {
err := mr.db.Session.Tx(func(sess db.Session) error {
err := applyMigration(sess, upgradeScript, *migration)
err := mr.db.Tx(func(db storage.DB) error {
err := applyMigration(db, upgradeScript, *migration)
if err != nil {
return err
}
Expand All @@ -147,16 +143,16 @@ func (mr migrationDBRepo) ApplyWithTx(
}

func applyMigration(
db db.Session,
db storage.DB,
upgradeScript string,
migration models.Migration,
) error {
_, err := db.SQL().Exec(upgradeScript)
_, err := db.Exec(upgradeScript)
if err != nil {
return fmt.Errorf("unable to execute upgrade script: %w", err)
}

_, err = db.SQL().InsertInto("bolt_migrations").Columns("version").Values(migration.Version).Exec()
_, err = db.Exec("INSERT INTO bolt_migrations(version) VALUES(?)", migration.Version)
if err != nil {
return fmt.Errorf(
"unable to insert migration: %w",
Expand All @@ -174,7 +170,7 @@ func (mr migrationDBRepo) Revert(
downgradeScript string,
migration *models.Migration,
) error {
err := revertMigration(mr.db.Session, downgradeScript, *migration)
err := revertMigration(mr.db, downgradeScript, *migration)
if err != nil {
return err
}
Expand All @@ -189,8 +185,8 @@ func (mr migrationDBRepo) RevertWithTx(
downgradeScript string,
migration *models.Migration,
) error {
err := mr.db.Session.Tx(func(sess db.Session) error {
err := revertMigration(sess, downgradeScript, *migration)
err := mr.db.Tx(func(db storage.DB) error {
err := revertMigration(db, downgradeScript, *migration)
if err != nil {
return err
}
Expand All @@ -205,16 +201,16 @@ func (mr migrationDBRepo) RevertWithTx(
}

func revertMigration(
db db.Session,
db storage.DB,
downgradeScript string,
migration models.Migration,
) error {
_, err := db.SQL().Exec(downgradeScript)
_, err := db.Exec(downgradeScript)
if err != nil {
return fmt.Errorf("unable to execute downgrade script: %w", err)
}

_, err = db.SQL().DeleteFrom("bolt_migrations").Where("version = ?", migration.Version).Exec()
_, err = db.Exec("DELETE FROM bolt_migrations WHERE version = ?", migration.Version)
if err != nil {
return fmt.Errorf(
"unable to remove reverted migration from bolt_migrations table: %w",
Expand Down
Loading

0 comments on commit 57689df

Please sign in to comment.