Transaction implementation #2
+53
-18
@@ -10,6 +10,7 @@ import (
|
|||||||
log "gitlab.com/gdulai/simpleloglvl"
|
log "gitlab.com/gdulai/simpleloglvl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Created and executes the DDL created by [simpleorm.ORM]
|
||||||
func ExecuteDDL(conn *simpleorm.DBConnection, orm *simpleorm.ORM) {
|
func ExecuteDDL(conn *simpleorm.DBConnection, orm *simpleorm.ORM) {
|
||||||
schema, err := orm.CreateSchema()
|
schema, err := orm.CreateSchema()
|
||||||
if err != nil {
|
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 {
|
type Transaction struct {
|
||||||
conn *simpleorm.DBConnection
|
conn *simpleorm.DBConnection
|
||||||
executions []*Exec[any]
|
executions []*Exec[any]
|
||||||
@@ -31,14 +34,20 @@ type Transaction struct {
|
|||||||
finished bool
|
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}
|
return &Transaction{conn: conn, executions: executions, finished: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The executions assigned to this transaction.
|
||||||
func (t *Transaction) Executions() []*Exec[any] {
|
func (t *Transaction) Executions() []*Exec[any] {
|
||||||
return t.executions
|
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 {
|
func (t *Transaction) ExecuteAtOnce() error {
|
||||||
if t.finished {
|
if t.finished {
|
||||||
return errors.New("Transaction already finished.")
|
return errors.New("Transaction already finished.")
|
||||||
@@ -56,11 +65,10 @@ func (t *Transaction) ExecuteAtOnce() error {
|
|||||||
for _, exec := range t.executions {
|
for _, exec := range t.executions {
|
||||||
err := (*exec).execute(nil, t.tx)
|
err := (*exec).execute(nil, t.tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rollbackErr := t.tx.Rollback()
|
rollbackErr := t.Rollback()
|
||||||
if rollbackErr != nil {
|
if rollbackErr != nil {
|
||||||
return rollbackErr
|
return rollbackErr
|
||||||
}
|
}
|
||||||
t.finished = true
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,34 +83,42 @@ func (t *Transaction) ExecuteAtOnce() error {
|
|||||||
return nil
|
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 {
|
if t.finished {
|
||||||
return errors.New("Transaction already finished.")
|
return errors.New("Transaction already finished.")
|
||||||
}
|
}
|
||||||
|
|
||||||
t.executions = append(t.executions, exec)
|
for _, exec := range execs {
|
||||||
if t.tx == nil {
|
execPtr := &exec
|
||||||
tx, err := t.conn.Begin()
|
t.executions = append(t.executions, execPtr)
|
||||||
t.tx = tx
|
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 {
|
if err != nil {
|
||||||
t.finished = true
|
rollbackErr := t.Rollback()
|
||||||
|
if rollbackErr != nil {
|
||||||
|
return rollbackErr
|
||||||
|
}
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finishes the transaction, commits the changes.
|
||||||
|
// This is terminal operation.
|
||||||
func (t *Transaction) Finish() error {
|
func (t *Transaction) Finish() error {
|
||||||
if t.finished {
|
if t.finished {
|
||||||
return errors.New("Transaction already finished.")
|
return errors.New("Transaction already finished.")
|
||||||
@@ -117,6 +133,25 @@ func (t *Transaction) Finish() error {
|
|||||||
return nil
|
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 {
|
type Exec[T any] interface {
|
||||||
Execute(conn *simpleorm.DBConnection) error
|
Execute(conn *simpleorm.DBConnection) error
|
||||||
execute(conn *simpleorm.DBConnection, tx *sql.Tx) error
|
execute(conn *simpleorm.DBConnection, tx *sql.Tx) error
|
||||||
|
|||||||
+132
-70
@@ -1,35 +1,22 @@
|
|||||||
package simpleorm_test
|
package simpleorm_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
simpleorm "git.gdulai.com/gdulai/simpleorm"
|
|
||||||
"git.gdulai.com/gdulai/simpleorm/exec"
|
"git.gdulai.com/gdulai/simpleorm/exec"
|
||||||
log "gitlab.com/gdulai/simpleloglvl"
|
log "gitlab.com/gdulai/simpleloglvl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cleanUp(dbFile string, conn *simpleorm.DBConnection) {
|
|
||||||
conn.Close()
|
|
||||||
os.Remove(dbFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSelectEmpty(t *testing.T) {
|
func TestSelectEmpty(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
selectExec, err := exec.CreateSelect[Test](orm, "")
|
selectExec, err := exec.CreateSelect[Test](orm, "")
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("Failed to create select. %s", err)
|
log.LogError("Failed to create select. %s", err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
@@ -53,15 +40,12 @@ func TestSelectEmpty(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsert(t *testing.T) {
|
func TestInsert(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
||||||
@@ -69,7 +53,6 @@ func TestInsert(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
insertErr := insertExec.Execute(conn)
|
insertErr := insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndSelectSingle insert failed: %s", err)
|
log.LogError("TestInsertAndSelectSingle insert failed: %s", err)
|
||||||
@@ -100,16 +83,13 @@ func TestInsert(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertMultiple(t *testing.T) {
|
func TestInsertMultiple(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
testObjSecond := Test{Int64Field: 12, IntField: 54, StringField: "fdsa"}
|
testObjSecond := Test{Int64Field: 12, IntField: 54, StringField: "fdsa"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert[Test](orm, testObj, testObjSecond)
|
insertExec, err := exec.NewInsert[Test](orm, testObj, testObjSecond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
||||||
@@ -117,7 +97,6 @@ func TestInsertMultiple(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
insertErr := insertExec.Execute(conn)
|
insertErr := insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndSelectSingle insert failed: %s", err)
|
log.LogError("TestInsertAndSelectSingle insert failed: %s", err)
|
||||||
@@ -155,15 +134,12 @@ func TestInsertMultiple(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertAndSelectSingle(t *testing.T) {
|
func TestInsertAndSelectSingle(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
log.LogError("TestInsertAndSelectSingle setup failed: %s", err)
|
||||||
@@ -178,7 +154,6 @@ func TestInsertAndSelectSingle(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
insertErr := insertExec.Execute(conn)
|
insertErr := insertExec.Execute(conn)
|
||||||
selectErr := selectExec.Execute(conn)
|
selectErr := selectExec.Execute(conn)
|
||||||
|
|
||||||
@@ -225,15 +200,12 @@ func TestInsertAndSelectSingle(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertSelectWithCompositePk(t *testing.T) {
|
func TestInsertSelectWithCompositePk(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := TestWithCompositePk{ID: 12, Name: "Test"}
|
testObj := TestWithCompositePk{ID: 12, Name: "Test"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertSelectWithCompositePk setup failed: %s", err)
|
log.LogError("TestInsertSelectWithCompositePk setup failed: %s", err)
|
||||||
@@ -248,7 +220,6 @@ func TestInsertSelectWithCompositePk(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
err = insertExec.Execute(conn)
|
err = insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertSelectWithCompositePk insert failed: %s", err)
|
log.LogError("TestInsertSelectWithCompositePk insert failed: %s", err)
|
||||||
@@ -282,14 +253,10 @@ func TestInsertSelectWithCompositePk(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertMultipleAndSelectWithParam(t *testing.T) {
|
func TestInsertMultipleAndSelectWithParam(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
// WHEN
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
testObjSecond := Test{Int64Field: 12, IntField: 54, StringField: "fdsa"}
|
testObjSecond := Test{Int64Field: 12, IntField: 54, StringField: "fdsa"}
|
||||||
|
|
||||||
@@ -314,8 +281,6 @@ func TestInsertMultipleAndSelectWithParam(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
|
|
||||||
err = insertExec.Execute(conn)
|
err = insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertMultipleAndSelectWithParam first insert failed: %s", err)
|
log.LogError("TestInsertMultipleAndSelectWithParam first insert failed: %s", err)
|
||||||
@@ -356,15 +321,12 @@ func TestInsertMultipleAndSelectWithParam(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertAndUpdate(t *testing.T) {
|
func TestInsertAndUpdate(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndUpdate setup failed: %s", err)
|
log.LogError("TestInsertAndUpdate setup failed: %s", err)
|
||||||
@@ -379,8 +341,6 @@ func TestInsertAndUpdate(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
|
|
||||||
err = insertExec.Execute(conn)
|
err = insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndUpdate insert failed: %s", err)
|
log.LogError("TestInsertAndUpdate insert failed: %s", err)
|
||||||
@@ -441,15 +401,12 @@ func TestInsertAndUpdate(t *testing.T) {
|
|||||||
|
|
||||||
func TestInsertAndDelete(t *testing.T) {
|
func TestInsertAndDelete(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestInsertAndDelete setup failed: %s", err)
|
log.LogError("TestInsertAndDelete setup failed: %s", err)
|
||||||
@@ -479,8 +436,6 @@ func TestInsertAndDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteExec, err := exec.NewDelete(orm, selectExec.Results())
|
deleteExec, err := exec.NewDelete(orm, selectExec.Results())
|
||||||
|
|
||||||
// WHEN
|
|
||||||
err = deleteExec.Execute(conn)
|
err = deleteExec.Execute(conn)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
@@ -509,14 +464,12 @@ func TestInsertAndDelete(t *testing.T) {
|
|||||||
|
|
||||||
func TestBoolInsertAndSelectSingle(t *testing.T) {
|
func TestBoolInsertAndSelectSingle(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(TestWithBool{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
testObj := TestWithBool{BoolField: true}
|
testObj := TestWithBool{BoolField: true}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestBoolInsertAndSelectSingle setup failed: %s", err)
|
log.LogError("TestBoolInsertAndSelectSingle setup failed: %s", err)
|
||||||
@@ -531,7 +484,6 @@ func TestBoolInsertAndSelectSingle(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
err = insertExec.Execute(conn)
|
err = insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestBoolInsertAndSelectSingle insert failed: %s", err)
|
log.LogError("TestBoolInsertAndSelectSingle insert failed: %s", err)
|
||||||
@@ -565,15 +517,13 @@ func TestBoolInsertAndSelectSingle(t *testing.T) {
|
|||||||
|
|
||||||
func TestTimeInsertAndSelectSingle(t *testing.T) {
|
func TestTimeInsertAndSelectSingle(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
orm := simpleorm.NewORM(TestWithTime{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
now := time.Now().UnixMilli()
|
now := time.Now().UnixMilli()
|
||||||
testObj := TestWithTime{TimeField: now}
|
testObj := TestWithTime{TimeField: now}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
insertExec, err := exec.NewInsert(orm, testObj)
|
insertExec, err := exec.NewInsert(orm, testObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestTimeInsertAndSelectSingle setup failed: %s", err)
|
log.LogError("TestTimeInsertAndSelectSingle setup failed: %s", err)
|
||||||
@@ -588,7 +538,6 @@ func TestTimeInsertAndSelectSingle(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHEN
|
|
||||||
err = insertExec.Execute(conn)
|
err = insertExec.Execute(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.LogError("TestTimeInsertAndSelectSingle insert failed: %s", err)
|
log.LogError("TestTimeInsertAndSelectSingle insert failed: %s", err)
|
||||||
@@ -619,3 +568,116 @@ func TestTimeInsertAndSelectSingle(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTransactionExecuteSimple(t *testing.T) {
|
||||||
|
// GIVEN
|
||||||
|
orm, conn := testSetup()
|
||||||
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
|
transaction := exec.NewTransaction(conn)
|
||||||
|
|
||||||
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
insertExec, err := exec.NewInsert[Test](orm, testObj)
|
||||||
|
if err != nil {
|
||||||
|
log.LogError("TestTransactionExecuteSimple failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transErr := transaction.Execute(&insertExec)
|
||||||
|
if transErr != nil {
|
||||||
|
transErr = transaction.Finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
if transErr != nil {
|
||||||
|
log.LogError("TestTransactionExecuteSimple failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
insertRes := insertExec.Results()
|
||||||
|
|
||||||
|
if len(insertRes) != 1 {
|
||||||
|
log.LogError("TestInsertAndSelectSingle test failed. Expected: 1, Actual: %s", len(insertRes))
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
singleRes := insertRes[0]
|
||||||
|
if singleRes.ID != 1 || singleRes.Int64Field != 54 || singleRes.IntField != 12 || singleRes.StringField != "asdf" {
|
||||||
|
log.LogError("TestInsertAndSelectSingle invalid result. Expected: %s, Actual: %s", testObj, singleRes)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTransactionRollback(t *testing.T) {
|
||||||
|
// GIVEN
|
||||||
|
orm, conn := testSetup()
|
||||||
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
|
transaction := exec.NewTransaction(conn)
|
||||||
|
|
||||||
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
insertExec, err := exec.NewInsert[Test](orm, testObj)
|
||||||
|
if err != nil {
|
||||||
|
log.LogError("TestTransactionRollback WHEN failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transErr := transaction.Execute(&insertExec)
|
||||||
|
if transErr != nil {
|
||||||
|
log.LogError("TestTransactionRollback WHEN failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selectExec, err := exec.CreateSelect[Test](orm, "id = ?", insertExec.Results()[0].ID)
|
||||||
|
if err != nil {
|
||||||
|
log.LogError("TestTransactionRollback WHEN failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transErr = transaction.Execute(&selectExec)
|
||||||
|
if transErr != nil {
|
||||||
|
log.LogError("TestTransactionRollback WHEN failed: %s", err)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeRollbackSelectRes := selectExec.Results()
|
||||||
|
rollbackErr := transaction.Rollback()
|
||||||
|
afterRollbackErr := selectExec.Execute(conn)
|
||||||
|
afterRollbackSelectRes := selectExec.Results()
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
if len(beforeRollbackSelectRes) != 1 {
|
||||||
|
log.LogError("TestTransactionExecuteSimple-THEN: Expected 1, Actual: %s", len(beforeRollbackSelectRes))
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if rollbackErr != nil {
|
||||||
|
log.LogError("TestTransactionExecuteSimple-THEN: rollback error: %s", rollbackErr)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if afterRollbackErr != nil {
|
||||||
|
log.LogError("TestTransactionExecuteSimple-THEN: after rollback select error: %s", rollbackErr)
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(afterRollbackSelectRes) != 0 {
|
||||||
|
log.LogError("TestTransactionExecuteSimple-THEN: Expected 0 after rollback select result")
|
||||||
|
t.Fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
simpleorm "git.gdulai.com/gdulai/simpleorm"
|
||||||
|
"git.gdulai.com/gdulai/simpleorm/exec"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
log "gitlab.com/gdulai/simpleloglvl"
|
log "gitlab.com/gdulai/simpleloglvl"
|
||||||
)
|
)
|
||||||
@@ -61,3 +63,18 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testSetup() (*simpleorm.ORM, *simpleorm.DBConnection) {
|
||||||
|
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
||||||
|
|
||||||
|
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
||||||
|
TestWithCompositePk{}, TestWithCompositeFk{}, TestWithBool{}, TestWithTime{})
|
||||||
|
exec.ExecuteDDL(conn, orm)
|
||||||
|
|
||||||
|
return orm, conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanUp(dbFile string, conn *simpleorm.DBConnection) {
|
||||||
|
conn.Close()
|
||||||
|
os.Remove(dbFile)
|
||||||
|
}
|
||||||
|
|||||||
+5
-17
@@ -3,26 +3,14 @@ package simpleorm_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
simpleorm "git.gdulai.com/gdulai/simpleorm"
|
|
||||||
"git.gdulai.com/gdulai/simpleorm/exec"
|
"git.gdulai.com/gdulai/simpleorm/exec"
|
||||||
"git.gdulai.com/gdulai/simpleorm/repository"
|
"git.gdulai.com/gdulai/simpleorm/repository"
|
||||||
log "gitlab.com/gdulai/simpleloglvl"
|
log "gitlab.com/gdulai/simpleloglvl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func repoTestSetup() (*simpleorm.ORM, *simpleorm.DBConnection) {
|
|
||||||
conn := simpleorm.OpenConnection("sqlite3", "file:test.db")
|
|
||||||
|
|
||||||
orm := simpleorm.NewORM(Test{}, TestWithFk{}, TestWithFkAndFkId{},
|
|
||||||
TestWithCompositePk{}, TestWithCompositeFk{})
|
|
||||||
|
|
||||||
exec.ExecuteDDL(conn, orm)
|
|
||||||
|
|
||||||
return orm, conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRepoSelectAll(t *testing.T) {
|
func TestRepoSelectAll(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
orm, conn := repoTestSetup()
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
@@ -48,7 +36,7 @@ func TestRepoSelectAll(t *testing.T) {
|
|||||||
|
|
||||||
func TestRepoSelectByPk(t *testing.T) {
|
func TestRepoSelectByPk(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
orm, conn := repoTestSetup()
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
@@ -74,7 +62,7 @@ func TestRepoSelectByPk(t *testing.T) {
|
|||||||
|
|
||||||
func TestRepoSelectByCompundPk(t *testing.T) {
|
func TestRepoSelectByCompundPk(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
orm, conn := repoTestSetup()
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
testObj := TestWithCompositePk{ID: 42069, Name: "Test"}
|
testObj := TestWithCompositePk{ID: 42069, Name: "Test"}
|
||||||
@@ -100,7 +88,7 @@ func TestRepoSelectByCompundPk(t *testing.T) {
|
|||||||
|
|
||||||
func TestRepoSave(t *testing.T) {
|
func TestRepoSave(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
orm, conn := repoTestSetup()
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
testObj := &Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := &Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
@@ -121,7 +109,7 @@ func TestRepoSave(t *testing.T) {
|
|||||||
|
|
||||||
func TestRepoDelete(t *testing.T) {
|
func TestRepoDelete(t *testing.T) {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
orm, conn := repoTestSetup()
|
orm, conn := testSetup()
|
||||||
defer cleanUp("test.db", conn)
|
defer cleanUp("test.db", conn)
|
||||||
|
|
||||||
testObj := &Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
testObj := &Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
|
||||||
|
|||||||
Reference in New Issue
Block a user