-
Notifications
You must be signed in to change notification settings - Fork 1
/
cache_db.go
119 lines (101 loc) · 2.52 KB
/
cache_db.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
package utils
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/sirupsen/logrus"
)
type CacheDB struct {
db *sql.DB
ttlSeconds int
tableName string
}
func NewCacheDB(dbFile string, tableName string, ttlSeconds int) (*CacheDB, error) {
if dbFile == "" {
return nil, fmt.Errorf("cacheFile was not defined")
}
db, err := sql.Open("sqlite3", dbFile)
if err != nil {
return nil, err
}
sql := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s (
"CACHE_KEY" TEXT NOT NULL PRIMARY KEY,
"CACHE_VALUE" TEXT NOT NULL,
"LAST_ACCESS" TIMESTAMP
);`, tableName)
_, err = db.Exec(sql)
if err != nil {
return nil, err
}
logrus.Debugf("Cleaning up old cache entries")
sql = fmt.Sprintf(`DELETE FROM %s WHERE LAST_ACCESS <= DATETIME(CURRENT_TIMESTAMP, '-%d second');`, tableName, ttlSeconds)
_, err = db.Exec(sql)
if err != nil {
return nil, err
}
return &CacheDB{
db: db,
ttlSeconds: ttlSeconds,
tableName: tableName},
nil
}
func (c *CacheDB) PutValue(cacheKey string, cacheContents string) error {
logrus.Debugf("Saving cache contents")
sql := fmt.Sprintf(`DELETE FROM %s WHERE CACHE_KEY = ?;`, c.tableName)
statement, err := c.db.Prepare(sql)
if err != nil {
return err
}
_, err = statement.Exec(cacheKey)
if err != nil {
return err
}
sql = fmt.Sprintf(`INSERT INTO %s (CACHE_KEY, CACHE_VALUE, LAST_ACCESS) VALUES (?, ?, CURRENT_TIMESTAMP);`, c.tableName)
statement, err = c.db.Prepare(sql)
if err != nil {
return err
}
_, err = statement.Exec(cacheKey, cacheContents)
if err != nil {
return err
}
return nil
}
func (c *CacheDB) GetValue(cacheKey string) (*string, error) {
logrus.Debugf("Getting cache contents")
sql := fmt.Sprintf(`SELECT CACHE_VALUE FROM %s WHERE CACHE_KEY = ? AND LAST_ACCESS > DATETIME(CURRENT_TIMESTAMP, '-%d second');`, c.tableName, c.ttlSeconds)
statement, err := c.db.Prepare(sql)
if err != nil {
return nil, err
}
rows, err := statement.Query(cacheKey)
if err != nil {
return nil, err
}
defer rows.Close()
var result *string
for rows.Next() {
resultStr := ""
err = rows.Scan(&resultStr)
if err != nil {
return nil, err
}
result = &resultStr
}
if result != nil {
// mark last accessed time
sql := fmt.Sprintf(`UPDATE %s SET LAST_ACCESS = CURRENT_TIMESTAMP WHERE CACHE_KEY = ?`, c.tableName)
stmt, err := c.db.Prepare(sql)
if err != nil {
return nil, err
}
_, err = stmt.Exec(cacheKey)
if err != nil {
return nil, err
}
}
return result, nil
}
func (c *CacheDB) Close() {
c.db.Close()
}