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
|
package sqlite
import (
"database/sql"
"delayed.link/storage"
"encoding/json"
"errors"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3"
"github.com/spf13/pflag"
"log"
)
var (
dbFile = pflag.StringP("dbfile", "d", "delayedlink.db", "")
)
type SqliteStorage struct {
*sql.DB
}
func (s *SqliteStorage) Close() error {
return s.DB.Close()
}
func (s *SqliteStorage) Save(item storage.Link) (uuid.UUID, error) {
stmt, err := s.Prepare("INSERT INTO links VALUES (?, ?)")
if err != nil {
return storage.Null, err
}
id := uuid.New()
item.Id = id
obj, err := item.Serialize()
if err != nil {
return storage.Null, err
}
_, err = stmt.Exec(id, obj)
if err != nil {
return storage.Null, err
}
return id, nil
}
const insertStatement = `SELECT (obj) FROM links WHERE id = ? LIMIT 1`
func (s *SqliteStorage) Load(key uuid.UUID) (*storage.Link, error) {
stmt, err := s.DB.Prepare(insertStatement)
if err != nil {
return nil, err
}
rows, err := stmt.Query(key.String())
if err != nil {
return nil, err
}
defer rows.Close()
var link *storage.Link
var data []byte
if !rows.Next() {
return nil, storage.NotFoundError
}
err = rows.Scan(&data)
if err != nil {
return nil, err
}
err = json.Unmarshal(data, &link)
if err != nil {
return nil, err
}
return link, nil
}
const creation_sql = `CREATE TABLE IF NOT EXISTS links (
id UUID PRIMARY KEY,
obj JSONB NOT NULL
);`
func New() *SqliteStorage {
db, err := sql.Open("sqlite3", *dbFile)
if err != nil {
log.Panic(err)
}
_, err = db.Exec(creation_sql)
if err != nil {
panic(err)
}
return &SqliteStorage{
db,
}
}
const deleteQuery = `DELETE FROM links WHERE id = ?`
var NotFoundError = errors.New("entry not found")
func (s *SqliteStorage) Delete(item storage.Link) error {
stmt, err := s.DB.Prepare(deleteQuery)
if err != nil {
return err
}
res, err := stmt.Exec(item.Id)
if err != nil {
return err
}
if aff, err := res.RowsAffected(); aff < 1 || err != nil {
if err == nil {
return NotFoundError
}
return err
}
return nil
}
const updateQuery = `UPDATE links SET obj = ? WHERE id = ?`
func (s *SqliteStorage) Update(item storage.Link) error {
stmt, err := s.DB.Prepare(updateQuery)
if err != nil {
return err
}
obj, err := item.Serialize()
if err != nil {
return err
}
_, err = stmt.Exec(item.Id, obj)
if err != nil {
return err
}
return nil
}
|