-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlite_repository.go
130 lines (108 loc) · 2.71 KB
/
sqlite_repository.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
package website
import (
"database/sql"
"errors"
"github.com/mattn/go-sqlite3"
)
var (
ErrDuplicate = errors.New("Record already exists")
ErrNotExists = errors.New("Row not exists")
ErrUpdateFailed = errors.New("Update failed")
ErrDeleteFailed = errors.New("delete failed")
)
type SQLiteRepository struct {
db *sql.DB
}
func NewSQLiteRepository(db *sql.DB) *SQLiteRepository {
return &SQLiteRepository{
db: db,
}
}
func (r *SQLiteRepository) Migrate() error {
query := `
CREATE TABLE IF NOT EXISTS websites(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
url TEXT NOT NULL,
rank INTEGER NOT NULL
);
`
_, err := r.db.Exec(query)
return err
}
func (r *SQLiteRepository) Create(website Website) (*Website, error) {
res, err := r.db.Exec("INSERT INTO websites(name, url, rank) values(?,?,?)", website.Name, website.URL, website.Rank)
if err != nil {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) {
if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) {
return nil, ErrDuplicate
}
}
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
website.ID = id
return &website, nil
}
func (r *SQLiteRepository) All() ([]Website, error) {
rows, err := r.db.Query("SELECT * FROM websites")
if err != nil {
return nil, err
}
defer rows.Close()
var all []Website
for rows.Next() {
var website Website
if err := rows.Scan(&website.ID, &website.Name, &website.URL, &website.Rank); err != nil {
return nil, err
}
all = append(all, website)
}
return all, nil
}
func (r *SQLiteRepository) GetByName(name string) (*Website, error) {
row := r.db.QueryRow("SELECT * FROM websites WHERE name = ?", name)
var website Website
if err := row.Scan(&website.ID, &website.Name, &website.URL, &website.Rank); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotExists
}
return nil, err
}
return &website, nil
}
func (r *SQLiteRepository) Update(id int64, updated Website) (*Website, error) {
if id == 0 {
return nil, errors.New("invalid updated ID")
}
res, err := r.db.Exec("UPDATE websites SET name = ?, url = ?, rank = ? WHERE id = ?", updated.Name, updated.URL, updated.Rank, id)
if err != nil {
return nil, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, err
}
if rowsAffected == 0 {
return nil, ErrUpdateFailed
}
return &updated, nil
}
func (r *SQLiteRepository) Delete(id int64) error {
res, err := r.db.Exec("DELETE FROM websites WHERE id = ?", id)
if err != nil {
return err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return ErrDeleteFailed
}
return err
}