Skip to content

Proof-of-concept of passing an interface rather than *sql.DB to database drivers #374

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions database/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,40 @@ type Config struct {
StatementTimeout time.Duration
}

type SQLWrapper struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we need this. e.g. *sql.DB should work
It's probably worth documenting that *sql.DB satisfies this interface the interface should be moved up a package to migrate/database

*sql.DB
}

func (w *SQLWrapper) Conn(ctx context.Context) (Conn, error) {
return w.DB.Conn(ctx)
}

type Conn interface {
Close() error
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
}

type DB interface {
Close() error
Ping() error
QueryRow(query string, args ...interface{}) *sql.Row
Conn(ctx context.Context) (Conn, error)
}

type Postgres struct {
// Locking and unlocking need to use the same connection
conn *sql.Conn
db *sql.DB
conn Conn
db DB
isLocked bool

// Open and WithInstance need to guarantee that config is never nil
config *Config
}

func WithInstance(instance *sql.DB, config *Config) (database.Driver, error) {
func WithInterface(instance DB, config *Config) (database.Driver, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to keep the same method WithInstance() and just change the param to use the interface.

if config == nil {
return nil, ErrNilConfig
}
Expand Down Expand Up @@ -111,6 +134,10 @@ func WithInstance(instance *sql.DB, config *Config) (database.Driver, error) {
return px, nil
}

func WithInstance(instance *sql.DB, config *Config) (database.Driver, error) {
return WithInterface(&SQLWrapper{instance}, config)
}

func (p *Postgres) Open(url string) (database.Driver, error) {
purl, err := nurl.Parse(url)
if err != nil {
Expand Down