2024-10-12 20:41:30 +03:00
|
|
|
package sqlite
|
2024-10-12 18:39:38 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"errors"
|
|
|
|
"log/slog"
|
|
|
|
"os"
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
"git.a71.su/Andrew71/pye/storage"
|
2024-10-12 18:39:38 +03:00
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
)
|
|
|
|
|
|
|
|
const create string = `
|
|
|
|
CREATE TABLE "users" (
|
|
|
|
"uuid" TEXT NOT NULL UNIQUE,
|
|
|
|
"email" TEXT NOT NULL UNIQUE,
|
|
|
|
"password" TEXT NOT NULL,
|
|
|
|
PRIMARY KEY("uuid")
|
|
|
|
);`
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
type SQLiteStorage struct {
|
|
|
|
db *sql.DB
|
2024-10-12 18:39:38 +03:00
|
|
|
}
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
func (s SQLiteStorage) AddUser(email, password string) error {
|
|
|
|
user, err := storage.NewUser(email, password)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err = s.db.Exec("insert into users (uuid, email, password) values ($1, $2, $3)",
|
2024-10-12 18:39:38 +03:00
|
|
|
user.Uuid.String(), user.Email, user.Hash)
|
|
|
|
if err != nil {
|
2024-10-12 20:41:30 +03:00
|
|
|
slog.Error("error adding user to database", "error", err, "user", user)
|
2024-10-12 18:39:38 +03:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
func (s SQLiteStorage) ById(uuid string) (storage.User, bool) {
|
|
|
|
row := s.db.QueryRow("select * from users where uuid = $1", uuid)
|
|
|
|
user := storage.User{}
|
2024-10-12 18:39:38 +03:00
|
|
|
err := row.Scan(&user.Uuid, &user.Email, &user.Hash)
|
|
|
|
|
|
|
|
return user, err == nil
|
|
|
|
}
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
func (s SQLiteStorage) ByEmail(email string) (storage.User, bool) {
|
|
|
|
row := s.db.QueryRow("select * from users where email = $1", email)
|
|
|
|
user := storage.User{}
|
2024-10-12 18:39:38 +03:00
|
|
|
err := row.Scan(&user.Uuid, &user.Email, &user.Hash)
|
|
|
|
|
|
|
|
return user, err == nil
|
|
|
|
}
|
|
|
|
|
2024-10-12 20:41:30 +03:00
|
|
|
func (s SQLiteStorage) EmailExists(email string) bool {
|
|
|
|
_, ok := s.ByEmail(email)
|
2024-10-12 18:39:38 +03:00
|
|
|
return ok
|
|
|
|
}
|
2024-10-12 20:41:30 +03:00
|
|
|
|
2024-10-12 21:45:00 +03:00
|
|
|
func MustLoadSQLite(dataFile string) SQLiteStorage {
|
|
|
|
if _, err := os.Stat(dataFile); errors.Is(err, os.ErrNotExist) {
|
2024-10-12 21:58:42 +03:00
|
|
|
os.Create(dataFile)
|
|
|
|
slog.Info("created sqlite3 database file", "file", dataFile)
|
2024-10-12 20:41:30 +03:00
|
|
|
}
|
2024-10-12 21:45:00 +03:00
|
|
|
db, err := sql.Open("sqlite3", dataFile)
|
2024-10-12 20:41:30 +03:00
|
|
|
if err != nil {
|
|
|
|
slog.Error("error opening database", "error", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2024-10-12 21:58:42 +03:00
|
|
|
statement, err := db.Prepare(create)
|
|
|
|
if err != nil {
|
|
|
|
if err.Error() != "table \"users\" already exists" {
|
|
|
|
slog.Info("error initialising database table", "error", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
statement.Exec()
|
2024-10-12 20:41:30 +03:00
|
|
|
}
|
2024-10-12 21:58:42 +03:00
|
|
|
|
2024-10-12 21:45:00 +03:00
|
|
|
slog.Info("loaded database", "file", dataFile)
|
2024-10-12 20:41:30 +03:00
|
|
|
return SQLiteStorage{db}
|
|
|
|
}
|