Skip to content

Commit

Permalink
feat(sqlc): add sqlc datastore (#2)
Browse files Browse the repository at this point in the history
* refactor: add bun datastore package

* feat(sqlc): add sqlc dep and config

* feat(sqlc): add sqlc statements

* feat(sqlc): add sqlc datastore

* feat(sqlc): add sqlc toggle env var
  • Loading branch information
rafael-piovesan authored Jan 19, 2022
1 parent a598bb3 commit 16899a2
Show file tree
Hide file tree
Showing 42 changed files with 1,669 additions and 85 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ deps: ## Install dependencies
go mod tidy
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
go install github.com/segmentio/golines@latest
go install github.com/kyleconroy/sqlc/cmd/sqlc@latest
go install github.com/vektra/mockery/cmd/mockery

migrate: ## Run db migrations (expects $DSN env var, so, run it with: 'DSN=<postgres dsn> make fixtures')
Expand All @@ -22,6 +23,9 @@ lint: ## Run linter
format: ## Format source code
golines . -m 120 -w --ignore-generated

sqlc: ## Generate sqlc files
sqlc generate

mock: ## Generate interfaces mocks
mockery -name Datastore
mockery -name RideUseCase
Expand Down
27 changes: 17 additions & 10 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package main

import (
"database/sql"
"log"
"strings"

rocketride "github.com/rafael-piovesan/go-rocket-ride"
"github.com/rafael-piovesan/go-rocket-ride/adapters/datastore"
"github.com/rafael-piovesan/go-rocket-ride/api/http"
bunstore "github.com/rafael-piovesan/go-rocket-ride/datastore/bun"
sqlcstore "github.com/rafael-piovesan/go-rocket-ride/datastore/sqlc"
"github.com/rafael-piovesan/go-rocket-ride/pkg/stripemock"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
_ "github.com/uptrace/bun/driver/pgdriver"
)

func main() {
Expand All @@ -21,15 +19,24 @@ func main() {
}

// database connection
dsn := cfg.DBSource
sqldb, err := sql.Open("pg", dsn)
da := strings.ToLower(cfg.DatastoreAccess)
var store rocketride.Datastore

switch da {
case "bun":
store, err = bunstore.NewStore(cfg.DBSource)
case "sqlc":
store, err = sqlcstore.NewStore(cfg.DBSource)
default:
log.Printf("invalid store type %v", cfg.DatastoreAccess)
store, err = bunstore.NewStore(cfg.DBSource)
}

log.Printf("using [%v] datastore access", da)
if err != nil {
log.Fatalf("cannot open database: %v", err)
}

db := bun.NewDB(sqldb, pgdialect.New())
store := datastore.NewStore(db)

// Replace the original Stripe API Backend with its mock
stripemock.Init()

Expand Down
10 changes: 6 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ const (
// Config stores all configuration of the application.
// The values are read by viper from a config file or environment variable.
type Config struct {
IdemKeyTimeout int `mapstructure:"IDEM_KEY_TIMEOUT" validate:"required"`
DBSource string `mapstructure:"DB_SOURCE" validate:"required"`
ServerAddress string `mapstructure:"SERVER_ADDRESS" validate:"required"`
StripeKey string `mapstructure:"STRIPE_KEY" validate:"required"`
IdemKeyTimeout int `mapstructure:"IDEM_KEY_TIMEOUT" validate:"required"`
DBSource string `mapstructure:"DB_SOURCE" validate:"required"`
ServerAddress string `mapstructure:"SERVER_ADDRESS" validate:"required"`
StripeKey string `mapstructure:"STRIPE_KEY" validate:"required"`
DatastoreAccess string `mapstructure:"DATASTORE_ACCESS" validate:"required,oneof=bun sqlc"`
}

// LoadConfig reads configuration from file or environment variables.
Expand All @@ -38,6 +39,7 @@ func LoadConfig(cfgPath string) (config Config, err error) {

// default config values
viper.SetDefault("IDEM_KEY_TIMEOUT", 5)
viper.SetDefault("DATASTORE_ACCESS", "bun")

// enable loading of env vars values
// it'll override the values in the config file
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastore
package bun

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//go:build integration
// +build integration

package datastore
package bun

import (
"context"
"database/sql"
"testing"

"github.com/brianvoe/gofakeit/v6"
Expand All @@ -17,9 +16,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tabbed/pqtype"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
)

func TestAuditRecord(t *testing.T) {
Expand All @@ -43,10 +39,8 @@ func TestAuditRecord(t *testing.T) {
require.NoError(t, err)

// conntect to database
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())

store := NewStore(db)
store, err := NewStore(dsn)
require.NoError(t, err)

t.Run("Create Audit Record", func(t *testing.T) {
ip := pqtype.CIDR{}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastore
package bun

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//go:build integration
// +build integration

package datastore
package bun

import (
"context"
"database/sql"
"fmt"
"testing"
"time"
Expand All @@ -18,9 +17,6 @@ import (
"github.com/rafael-piovesan/go-rocket-ride/pkg/testfixtures"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
)

func TestIdempotencyKey(t *testing.T) {
Expand All @@ -45,10 +41,8 @@ func TestIdempotencyKey(t *testing.T) {
require.NoError(t, err)

// conntect to database
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())

store := NewStore(db)
store, err := NewStore(dsn)
require.NoError(t, err)

// test entity
now := time.Now()
Expand Down
2 changes: 1 addition & 1 deletion adapters/datastore/ride.go → datastore/bun/ride.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastore
package bun

import (
"context"
Expand Down
12 changes: 3 additions & 9 deletions adapters/datastore/ride_test.go → datastore/bun/ride_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//go:build integration
// +build integration

package datastore
package bun

import (
"context"
"database/sql"
"testing"

"github.com/brianvoe/gofakeit/v6"
Expand All @@ -15,9 +14,6 @@ import (
"github.com/rafael-piovesan/go-rocket-ride/pkg/testfixtures"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
)

func TestRide(t *testing.T) {
Expand Down Expand Up @@ -51,10 +47,8 @@ func TestRide(t *testing.T) {
require.NoError(t, err)

// conntect to database
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())

store := NewStore(db)
store, err := NewStore(dsn)
require.NoError(t, err)

// test entity
ride := &entity.Ride{
Expand Down
75 changes: 75 additions & 0 deletions datastore/bun/sqlstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package bun

import (
"context"
"database/sql"
"fmt"
"runtime"

"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"

// loading bun's official Postgres driver.
_ "github.com/uptrace/bun/driver/pgdriver"

rocketride "github.com/rafael-piovesan/go-rocket-ride"
)

type sqlStore struct {
conn *bun.DB
db bun.IDB
}

func NewStore(dsn string) (s rocketride.Datastore, err error) {
sqldb, err := sql.Open("pg", dsn)
if err != nil {
return nil, err
}

db := bun.NewDB(sqldb, pgdialect.New())
s = &sqlStore{
conn: db,
db: db,
}
return
}

func (s *sqlStore) Atomic(ctx context.Context, fn func(store rocketride.Datastore) error) (err error) {
tx, err := s.conn.BeginTx(ctx, &sql.TxOptions{})
if err != nil {
return err
}

defer func() {
if p := recover(); p != nil {
_ = tx.Rollback()

switch e := p.(type) {
case runtime.Error:
panic(e)
case error:
err = fmt.Errorf("panic err: %v", p)
return
default:
panic(e)
}
}
if err != nil {
if rbErr := tx.Rollback(); rbErr != nil {
err = fmt.Errorf("tx err: %v, rb err: %v", err, rbErr)
}
} else {
err = tx.Commit()
}
}()

// TODO: check if it works for nested transactions as well
newStore := &sqlStore{
conn: s.conn,
db: tx,
}
err = fn(newStore)
return err
}

var _ rocketride.Datastore = (*sqlStore)(nil)
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//go:build integration
// +build integration

package datastore
package bun

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

Expand All @@ -19,9 +18,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tabbed/pqtype"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
)

func TestSQLStore(t *testing.T) {
Expand Down Expand Up @@ -55,10 +51,8 @@ func TestSQLStore(t *testing.T) {
require.NoError(t, err)

// connect to database
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())

store := NewStore(db)
store, err := NewStore(dsn)
require.NoError(t, err)

// test entities
ride := &entity.Ride{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastore
package bun

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//go:build integration
// +build integration

package datastore
package bun

import (
"context"
"database/sql"
"testing"

"github.com/rafael-piovesan/go-rocket-ride/entity"
Expand All @@ -14,9 +13,6 @@ import (
"github.com/rafael-piovesan/go-rocket-ride/pkg/testcontainer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
)

func TestStagedJob(t *testing.T) {
Expand All @@ -32,10 +28,8 @@ func TestStagedJob(t *testing.T) {
require.NoError(t, err)

// connect to database
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
db := bun.NewDB(sqldb, pgdialect.New())

store := NewStore(db)
store, err := NewStore(dsn)
require.NoError(t, err)

t.Run("Create Staged Job", func(t *testing.T) {
sj := &entity.StagedJob{
Expand Down
2 changes: 1 addition & 1 deletion adapters/datastore/user.go → datastore/bun/user.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastore
package bun

import (
"context"
Expand Down
Loading

0 comments on commit 16899a2

Please sign in to comment.