-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoinDB.go
160 lines (128 loc) · 3.93 KB
/
coinDB.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"context"
_ "github.com/mattn/go-sqlite3"
"log"
"time"
)
func awardCoin(award *awardRequest) error {
ctx := context.Background()
tx, err := db.BeginTx(ctx, nil)
if err != nil {
log.Println(err)
return err
}
// ignore rollback if the tx has been commited later in the function
defer tx.Rollback()
awardStatement, err := tx.Prepare("UPDATE students SET Coins = Coins + ? WHERE Rollno = ? ")
if err != nil {
log.Println("error while preparing award statement")
tx.Rollback()
return err
}
defer awardStatement.Close()
_, err = awardStatement.Exec(award.Award, award.Rollno)
if err != nil {
log.Println("error while awarding the student")
tx.Rollback()
return err
}
// TODO : Find a way to use these function in the
// transactions directly. Right now any such function call
// will read values which are not updated i.e. outside transactions
activityStatement, err := tx.Prepare("UPDATE students SET Activity = Activity + 1 WHERE Rollno = ? ")
if err != nil {
log.Println("error while preparing activity statement")
tx.Rollback()
return err
}
defer activityStatement.Close()
// Roll no are unique so atmax 1 row will be updated
_, err = activityStatement.Exec(award.Rollno)
if err != nil {
log.Println("error while updating student activity")
return err
}
// Update award table
recordStatement, err := tx.Prepare("INSERT INTO awards ( Time, AwardeeRollno, Amount ) VALUES(?,?,?)")
if err != nil {
log.Println("error while preparing award statement")
tx.Rollback()
return err
}
defer recordStatement.Close()
_, err = recordStatement.Exec(time.Now(), award.Rollno, award.Award)
if err != nil {
log.Println("error while recording the award the student")
tx.Rollback()
return err
}
err = tx.Commit()
return err
}
func transferCoin(transfer *transferRequest) error {
ctx := context.Background()
tx, err := db.BeginTx(ctx, nil)
if err != nil {
log.Println(err)
return err
}
// ignore rollback if the tx has been commited later in the function
defer tx.Rollback()
// Update sender balance
senderStatement, err := tx.Prepare("UPDATE students SET Coins = Coins - ? WHERE Rollno = ? ")
if err != nil {
log.Println("error while preparing award statement for sender")
tx.Rollback()
return err
}
defer senderStatement.Close()
_, err = senderStatement.Exec(transfer.Amount, transfer.FromRollno)
if err != nil {
log.Println("error while updating sender info")
tx.Rollback()
return err
}
// update Reciever balance
recieverStatement, err := tx.Prepare("UPDATE students SET Coins = Coins + ? WHERE Rollno = ? ")
if err != nil {
log.Println("error while preparing statement for reciever")
tx.Rollback()
return err
}
defer recieverStatement.Close()
if sameBatch(transfer.FromRollno, transfer.ToRollno) {
// A transfer between two people will lead
// to destruction of 2% _coin involved in the form of taxes.
transfer.Amount = (98 * transfer.Amount) / 100
} else {
// Across the batch transfer will cause a
// destruction of 33% of _coin.
transfer.Amount = (67 * transfer.Amount) / 100
}
_, err = recieverStatement.Exec(transfer.Amount, transfer.ToRollno)
if err != nil {
log.Println("error while updating reciever info")
tx.Rollback()
return err
}
// Update transfer table
recordStatement, err := tx.Prepare("INSERT INTO transfers ( Time , SenderRollno ,RecieverRollno , Amount ) VALUES(?,?,?,?)")
if err != nil {
log.Println("error while preparing record statement of transfer")
tx.Rollback()
return err
}
defer recordStatement.Close()
// TODO: The amount transferred is more than what has been
// TODO: Recorded. A new field name Tax is required in order
// TODO: Make this record table more accurate
_, err = recordStatement.Exec(time.Now(), transfer.FromRollno, transfer.ToRollno, transfer.Amount)
if err != nil {
log.Println("error while recording the transfer")
tx.Rollback()
return err
}
err = tx.Commit()
return err
}