This commit is contained in:
+53
-18
@@ -10,6 +10,7 @@ import (
|
||||
log "gitlab.com/gdulai/simpleloglvl"
|
||||
)
|
||||
|
||||
// Created and executes the DDL created by [simpleorm.ORM]
|
||||
func ExecuteDDL(conn *simpleorm.DBConnection, orm *simpleorm.ORM) {
|
||||
schema, err := orm.CreateSchema()
|
||||
if err != nil {
|
||||
@@ -24,6 +25,8 @@ func ExecuteDDL(conn *simpleorm.DBConnection, orm *simpleorm.ORM) {
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps and represents a DB transaction.
|
||||
// Allows for all at once or separate execution of [exec.Exec] implementations.
|
||||
type Transaction struct {
|
||||
conn *simpleorm.DBConnection
|
||||
executions []*Exec[any]
|
||||
@@ -31,14 +34,20 @@ type Transaction struct {
|
||||
finished bool
|
||||
}
|
||||
|
||||
func (t *Transaction) NewTransaction(conn *simpleorm.DBConnection, executions ...*Exec[any]) *Transaction {
|
||||
// Creates a new [exec.Transaction].
|
||||
// Can be initialized with a set of [exec.Exec]s.
|
||||
func NewTransaction(conn *simpleorm.DBConnection, executions ...*Exec[any]) *Transaction {
|
||||
return &Transaction{conn: conn, executions: executions, finished: false}
|
||||
}
|
||||
|
||||
// The executions assigned to this transaction.
|
||||
func (t *Transaction) Executions() []*Exec[any] {
|
||||
return t.executions
|
||||
}
|
||||
|
||||
// Executes all the [exec.Exec] implementations assigned to this transactions.
|
||||
// Begins, commits or rollbacks the transaction.
|
||||
// This is a terminal operation, the [exec.Transaction] is considered finished after calling this.
|
||||
func (t *Transaction) ExecuteAtOnce() error {
|
||||
if t.finished {
|
||||
return errors.New("Transaction already finished.")
|
||||
@@ -56,11 +65,10 @@ func (t *Transaction) ExecuteAtOnce() error {
|
||||
for _, exec := range t.executions {
|
||||
err := (*exec).execute(nil, t.tx)
|
||||
if err != nil {
|
||||
rollbackErr := t.tx.Rollback()
|
||||
rollbackErr := t.Rollback()
|
||||
if rollbackErr != nil {
|
||||
return rollbackErr
|
||||
}
|
||||
t.finished = true
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -75,34 +83,42 @@ func (t *Transaction) ExecuteAtOnce() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Transaction) Execute(exec *Exec[any]) error {
|
||||
// Executes and assigns the passed [exec.Exec]s to the Transaction.
|
||||
// Calls rollback in case of an error.
|
||||
// This is NOT a terminal operation, transactions still has to be committed.
|
||||
func (t *Transaction) Execute(execs ...Exec[any]) error {
|
||||
if t.finished {
|
||||
return errors.New("Transaction already finished.")
|
||||
}
|
||||
|
||||
t.executions = append(t.executions, exec)
|
||||
if t.tx == nil {
|
||||
tx, err := t.conn.Begin()
|
||||
t.tx = tx
|
||||
for _, exec := range execs {
|
||||
execPtr := &exec
|
||||
t.executions = append(t.executions, execPtr)
|
||||
if t.tx == nil {
|
||||
tx, err := t.conn.Begin()
|
||||
t.tx = tx
|
||||
if err != nil {
|
||||
t.finished = true
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err := (*execPtr).execute(nil, t.tx)
|
||||
if err != nil {
|
||||
t.finished = true
|
||||
rollbackErr := t.Rollback()
|
||||
if rollbackErr != nil {
|
||||
return rollbackErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err := (*exec).execute(nil, t.tx)
|
||||
if err != nil {
|
||||
rollbackErr := t.tx.Rollback()
|
||||
if rollbackErr != nil {
|
||||
return rollbackErr
|
||||
}
|
||||
t.finished = true
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Finishes the transaction, commits the changes.
|
||||
// This is terminal operation.
|
||||
func (t *Transaction) Finish() error {
|
||||
if t.finished {
|
||||
return errors.New("Transaction already finished.")
|
||||
@@ -117,6 +133,25 @@ func (t *Transaction) Finish() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rollbacks and aborts the transaction.
|
||||
// This is a terminal operation.
|
||||
func (t *Transaction) Rollback() error {
|
||||
if t.finished {
|
||||
return errors.New("Transaction already finished.")
|
||||
}
|
||||
|
||||
if t.tx == nil {
|
||||
return errors.New("Transaction is nil.")
|
||||
}
|
||||
|
||||
rollbackErr := t.tx.Rollback()
|
||||
if rollbackErr != nil {
|
||||
return rollbackErr
|
||||
}
|
||||
t.finished = true
|
||||
return nil
|
||||
}
|
||||
|
||||
type Exec[T any] interface {
|
||||
Execute(conn *simpleorm.DBConnection) error
|
||||
execute(conn *simpleorm.DBConnection, tx *sql.Tx) error
|
||||
|
||||
Reference in New Issue
Block a user