Last active
December 19, 2023 12:18
-
-
Save byrnedo/b60c6f08bf74576f09fadeac7773c3d8 to your computer and use it in GitHub Desktop.
Repo setup for go that lets you use transactions transparently
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package repo | |
import ( | |
"context" | |
"database/sql/driver" | |
"github.com/jmoiron/sqlx" | |
) | |
// can be either a *sqlx.DB or a *sqlx.Tx | |
// should have methods that are common to both | |
type executor interface { | |
sqlx.ExtContext | |
SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error | |
GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error | |
} | |
type Repo interface { | |
Begin(ctx context.Context) (Repo, error) | |
// has Commit and Rollback sigs | |
driver.Tx | |
// TODD ADD YOUR OTHER METHODS HERE | |
InsertFoo(context.Context, *Foo) error | |
} | |
// Our implementation | |
type SqlRepo struct { | |
DB *sqlx.DB | |
// if this is a normal instance it'll be *sql.DB, otherwise a *sqlx.Tx | |
executor | |
} | |
func (r SqlRepo) Begin(ctx context.Context) (Repo, error) { | |
exr, err := r.DB.BeginTxx(ctx, &sql.TxOptions{}) | |
if err != nil { | |
return nil, err | |
} | |
return SqlRepo{DB: r.DB, executor: exr}, nil | |
} | |
func (r SqlRepo) Commit() (err error) { | |
if e, ok := r.executor.(*sqlx.Tx); ok { | |
return e.Commit() | |
} | |
return errors.New("not in a transaction") | |
} | |
func (r SqlRepo) Rollback() error { | |
if e, ok := r.executor.(*sqlx.Tx); ok { | |
return e.Rollback() | |
} | |
return errors.New("not in a transaction") | |
} | |
type Foo struct { | |
ID string | |
Name string | |
CreatedAt time.Time `db:"created_at"` | |
} | |
func (r SqlRepo) InsertFoo(ctx context.Context, thing *Foo) error { | |
return r.executor.GetContext(ctx, thing, `INSERT INTO foo (name) VALUES ($1) | |
RETURNING id, created_at | |
`, thing.Name) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment