-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlite.go
128 lines (96 loc) · 2.89 KB
/
sqlite.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
package sqlite
import (
"context"
"database/sql"
"errors"
"fmt"
"github.com/markraiter/auth-service/internal/domain/models"
"github.com/markraiter/auth-service/internal/storage"
"github.com/mattn/go-sqlite3"
)
type Storage struct {
db *sql.DB
}
// New creates a new instance of the SQLite storage.
func New(storagePath string) (*Storage, error) {
const op = "storage.sqlite.New"
// file path to DB
db, err := sql.Open("sqlite3", storagePath)
if err != nil {
return nil, fmt.Errorf("%s: %w", op, err)
}
return &Storage{db: db}, nil
}
func (s *Storage) SaveUser(ctx context.Context, email string, passHash []byte) (int, error) {
const op = "storage.sqlite.SaveUser"
// query
stmt, err := s.db.Prepare("INSERT INTO users(email, pass_hash) VALUES(?, ?)")
if err != nil {
return 0, fmt.Errorf("%s: %w", op, err)
}
res, err := stmt.ExecContext(ctx, email, passHash)
if err != nil {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) && sqliteErr.ExtendedCode == sqlite3.ErrConstraintUnique {
return 0, fmt.Errorf("%s: %w", op, storage.ErrUserExists)
}
return 0, fmt.Errorf("%s: %w", op, err)
}
// getiing ID of the created user
id, err := res.LastInsertId()
if err != nil {
return 0, fmt.Errorf("%s: %w", op, err)
}
return int(id), nil
}
func (s *Storage) User(ctx context.Context, email string) (*models.User, error) {
const op = "storage.sqlite.User"
stmt, err := s.db.Prepare("SELECT id, email, pass_hash FROM users WHERE email = ?")
if err != nil {
return nil, fmt.Errorf("%s: %w", op, err)
}
row := stmt.QueryRowContext(ctx, email)
var user models.User
err = row.Scan(&user.ID, &user.Email, &user.PassHash)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("%s: %w", op, storage.ErrUserNotFound)
}
return nil, fmt.Errorf("%s: %w", op, err)
}
return &user, nil
}
func (s *Storage) IsAdmin(ctx context.Context, userID int) (bool, error) {
const op = "storage.sqlte.IsAdmin"
stmt, err := s.db.Prepare("SELECT is_admin FROM users WHERE id = ?")
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
row := stmt.QueryRowContext(ctx, userID)
var isAdmin bool
err = row.Scan(&isAdmin)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, fmt.Errorf("%s: %w", op, storage.ErrAppNotFound)
}
return false, fmt.Errorf("%s: %w", op, err)
}
return isAdmin, nil
}
func (s *Storage) App(ctx context.Context, id int) (*models.App, error) {
const op = "storage.sqlite.App"
stmt, err := s.db.Prepare("SELECT id, name, secret FROM apps WHERE id = ?")
if err != nil {
return nil, fmt.Errorf("%s: %w", op, err)
}
row := stmt.QueryRowContext(ctx, id)
var app models.App
err = row.Scan(&app.ID, &app.Name, &app.Secret)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("%s: %w", op, storage.ErrAppNotFound)
}
return nil, fmt.Errorf("%s: %w", op, err)
}
return &app, nil
}