Skip to content

Commit

Permalink
rollback transaction when failure in update
Browse files Browse the repository at this point in the history
  • Loading branch information
ax4w committed Nov 20, 2023
1 parent 0e67c60 commit 89b5351
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 4 deletions.
41 changes: 41 additions & 0 deletions gorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,47 @@ func (g *Gorage) FromTable(name string) *Table {
}
}

func (g *Gorage) copyTableToTable(name string, t *Table) {
if !g.TableExists(name) {
return
}
for i, v := range g.Tables {
if v.Name == name {
g.Tables[i].Columns = t.Columns
g.Tables[i].Rows = t.Rows
}
}
}

func (g *Gorage) copyTable(name string) Table {
if !g.TableExists(name) {
return Table{}
}
for _, v := range g.Tables {
if v.Name == name {
t := Table{
host: v.host,
p: v.p,
t: transaction{
q: v.t.q.n,
},
}
for _, c := range v.Columns {
t.Columns = append(t.Columns, c)
}
for _, r := range v.Rows {
var a []interface{}
for _, t1 := range r {
a = append(a, t1)
}
t.Rows = append(t.Rows, a)
}
return t
}
}
return Table{}
}

func (g *Gorage) RemoveTable(name string) *Gorage {
if !g.TableExists(name) {
return g
Expand Down
22 changes: 19 additions & 3 deletions gorage_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,22 @@ func (g *Table) Update(d map[string]interface{}) *Table {
}
}

func (g *Table) Wait() {
for g.t.q.Head() != nil {

}
}

func (g *Table) update(data map[string]interface{}) *Table {
//g.Lock()
rt := g.host.FromTable(g.Name) // we need to get the table again to do persistent changes to it in memory

rtCopy := g.host.copyTable(g.Name)
var rt *Table
for i, v := range g.host.Tables {
if v.Name == g.Name {
rt = &g.host.Tables[i]
}
}
for _, v := range g.Rows {
for i, r := range rt.Rows {
if computeHash(v) != computeHash(r) {
Expand All @@ -321,7 +334,8 @@ func (g *Table) update(data map[string]interface{}) *Table {
for key, val := range data {
c, index := rt.getColAndIndexByName(key)
if c == nil || !validateDatatype(val, *c) {
panic("No matching column found or mismatch datatype")
g.host.copyTableToTable(g.Name, &rtCopy)
return rt
}
rt.Rows[i][index] = val
if g.host.Log {
Expand Down Expand Up @@ -485,7 +499,9 @@ func (g *Table) insert(data []interface{}) *Table {
return g
}
for i, v := range g.Columns {
validateDatatype(data[i], v)
if !validateDatatype(data[i], v) {
return g
}
}
g.Rows = append(g.Rows, data)
return g
Expand Down
2 changes: 1 addition & 1 deletion transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func transactionManger(t *Table) {
break
case actionUpdate:
p := d.payload[0].(map[string]interface{})
d.c <- t.Update(p)
d.c <- t.update(p)
break
case actionAddColumn:
name := d.payload[0].(string)
Expand Down
28 changes: 28 additions & 0 deletions transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,34 @@ import (
"time"
)

func TestRollback(t *testing.T) {
if fileExists("./transaction") {
err := os.Remove("./transaction")
if err != nil {
t.Fatalf("Error removing old test file")
return
}
}
g := Create("./transaction", false, false)
table := g.CreateTable("User")
if table == nil {
t.Fatalf("Table not created")
}
table.AddColumn("Name", STRING)
table.AddColumn("Age", INT)
table.Insert([]interface{}{"Carl", 20})
table.Update(map[string]interface{}{
"Name": "Bob",
"Age": "30",
})
res := table.Select([]string{"Name"})
rowZero := res.Rows[0]
if rowZero[0].(string) != "Carl" {
t.Fatalf("Rollback failed")
}
g.Save()
}

func TestAll(t *testing.T) {
if fileExists("./transaction") {
err := os.Remove("./transaction")
Expand Down

0 comments on commit 89b5351

Please sign in to comment.