Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit 89b5351

Browse files
committed
rollback transaction when failure in update
1 parent 0e67c60 commit 89b5351

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed

gorage.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,47 @@ func (g *Gorage) FromTable(name string) *Table {
4848
}
4949
}
5050

51+
func (g *Gorage) copyTableToTable(name string, t *Table) {
52+
if !g.TableExists(name) {
53+
return
54+
}
55+
for i, v := range g.Tables {
56+
if v.Name == name {
57+
g.Tables[i].Columns = t.Columns
58+
g.Tables[i].Rows = t.Rows
59+
}
60+
}
61+
}
62+
63+
func (g *Gorage) copyTable(name string) Table {
64+
if !g.TableExists(name) {
65+
return Table{}
66+
}
67+
for _, v := range g.Tables {
68+
if v.Name == name {
69+
t := Table{
70+
host: v.host,
71+
p: v.p,
72+
t: transaction{
73+
q: v.t.q.n,
74+
},
75+
}
76+
for _, c := range v.Columns {
77+
t.Columns = append(t.Columns, c)
78+
}
79+
for _, r := range v.Rows {
80+
var a []interface{}
81+
for _, t1 := range r {
82+
a = append(a, t1)
83+
}
84+
t.Rows = append(t.Rows, a)
85+
}
86+
return t
87+
}
88+
}
89+
return Table{}
90+
}
91+
5192
func (g *Gorage) RemoveTable(name string) *Gorage {
5293
if !g.TableExists(name) {
5394
return g

gorage_table.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,22 @@ func (g *Table) Update(d map[string]interface{}) *Table {
307307
}
308308
}
309309

310+
func (g *Table) Wait() {
311+
for g.t.q.Head() != nil {
312+
313+
}
314+
}
315+
310316
func (g *Table) update(data map[string]interface{}) *Table {
311317
//g.Lock()
312-
rt := g.host.FromTable(g.Name) // we need to get the table again to do persistent changes to it in memory
318+
319+
rtCopy := g.host.copyTable(g.Name)
320+
var rt *Table
321+
for i, v := range g.host.Tables {
322+
if v.Name == g.Name {
323+
rt = &g.host.Tables[i]
324+
}
325+
}
313326
for _, v := range g.Rows {
314327
for i, r := range rt.Rows {
315328
if computeHash(v) != computeHash(r) {
@@ -321,7 +334,8 @@ func (g *Table) update(data map[string]interface{}) *Table {
321334
for key, val := range data {
322335
c, index := rt.getColAndIndexByName(key)
323336
if c == nil || !validateDatatype(val, *c) {
324-
panic("No matching column found or mismatch datatype")
337+
g.host.copyTableToTable(g.Name, &rtCopy)
338+
return rt
325339
}
326340
rt.Rows[i][index] = val
327341
if g.host.Log {
@@ -485,7 +499,9 @@ func (g *Table) insert(data []interface{}) *Table {
485499
return g
486500
}
487501
for i, v := range g.Columns {
488-
validateDatatype(data[i], v)
502+
if !validateDatatype(data[i], v) {
503+
return g
504+
}
489505
}
490506
g.Rows = append(g.Rows, data)
491507
return g

transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func transactionManger(t *Table) {
4646
break
4747
case actionUpdate:
4848
p := d.payload[0].(map[string]interface{})
49-
d.c <- t.Update(p)
49+
d.c <- t.update(p)
5050
break
5151
case actionAddColumn:
5252
name := d.payload[0].(string)

transaction_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@ import (
66
"time"
77
)
88

9+
func TestRollback(t *testing.T) {
10+
if fileExists("./transaction") {
11+
err := os.Remove("./transaction")
12+
if err != nil {
13+
t.Fatalf("Error removing old test file")
14+
return
15+
}
16+
}
17+
g := Create("./transaction", false, false)
18+
table := g.CreateTable("User")
19+
if table == nil {
20+
t.Fatalf("Table not created")
21+
}
22+
table.AddColumn("Name", STRING)
23+
table.AddColumn("Age", INT)
24+
table.Insert([]interface{}{"Carl", 20})
25+
table.Update(map[string]interface{}{
26+
"Name": "Bob",
27+
"Age": "30",
28+
})
29+
res := table.Select([]string{"Name"})
30+
rowZero := res.Rows[0]
31+
if rowZero[0].(string) != "Carl" {
32+
t.Fatalf("Rollback failed")
33+
}
34+
g.Save()
35+
}
36+
937
func TestAll(t *testing.T) {
1038
if fileExists("./transaction") {
1139
err := os.Remove("./transaction")

0 commit comments

Comments
 (0)