-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
117 lines (105 loc) · 2.4 KB
/
util.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
package main
import (
"bytes"
"crypto/sha512"
"encoding/gob"
)
// TaskLength is a maximum length of a gob containing a task in DB.
// We got this value empirically.
const TaskLength = 6 * 1 << 10
const MaxAttempts = 2
// get maximum id in table `tab`
func maxid(tab string) (u int, err error) {
row := dbconn.QueryRow(`select max(id) from ` + tab)
err = row.Scan(&u)
if err != nil {
return 0, err
}
return
}
// gets a hash of password string
func sesh(passw string) int32 {
var hasher = sha512.New()
hashs := hasher.Sum([]byte(passw))
hash := int32(hashs[1]) |
int32(hashs[2])<<8 |
int32(hashs[3])<<16 |
int32(hashs[4])<<24
return hash
}
func task2gob(tk *Task) ([]byte, error) {
buf := bytes.NewBuffer(make([]byte, 0, TaskLength))
ge := gob.NewEncoder(buf)
err := ge.Encode(tk)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func gob2task(btk []byte) (tk *Task, err error) {
gd := gob.NewDecoder(bytes.NewBuffer(btk))
tk = new(Task)
err = gd.Decode(tk)
return
}
func theory2gob(th *Theory) ([]byte, error) {
buf := bytes.NewBuffer(make([]byte, 0, TaskLength))
ge := gob.NewEncoder(buf)
err := ge.Encode(th)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func gob2theory(btk []byte) (th *Theory, err error) {
gd := gob.NewDecoder(bytes.NewBuffer(btk))
th = new(Theory)
err = gd.Decode(th)
return
}
// this function tries to fix incorrect data sent by client
func taskfilter(tk *Task) *Task {
if tk.Difficulty > 3 {
tk.Difficulty = 3
}
if tk.Difficulty < 1 {
tk.Difficulty = 1
}
return tk
}
// readtask loads task by ID from file in location set on init
func readtask(tid TaskID) (*Task, error) {
buf := make([]byte, 0, TaskLength)
row := dbconn.QueryRow("select data from tasks where id = $1", tid)
err := row.Scan(buf)
if err != nil {
return nil, err
}
tk, err := gob2task(buf)
if err != nil {
return nil, err
}
return tk, nil
}
// writetask writes task to the store
func writetask(tk *Task, tid TaskID, thid TheoryID) error {
var err error
// FIXME
query := `
case when select id from tasks is not null then
insert into tasks (id, data, theoryid) values ($1, $2, $3)
else
update values set data = $3 where id = $1
update values set theoryid = $3 where id = $1
end`
tk = taskfilter(tk)
btk, err := task2gob(tk)
if err != nil {
return err
}
_, err = dbconn.Exec(query, tid, btk, thid)
if err != nil {
return err
}
return nil
}