166 lines
4.1 KiB
Go
166 lines
4.1 KiB
Go
package lishwist
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"lishwist/core/internal/db"
|
|
"lishwist/core/internal/normalize"
|
|
)
|
|
|
|
type User struct {
|
|
Id string
|
|
// TODO: rename to DisplayName
|
|
NormalName string
|
|
Name string
|
|
Reference string
|
|
IsAdmin bool
|
|
IsLive bool
|
|
}
|
|
|
|
func queryManyUsers(query string, args ...any) ([]User, error) {
|
|
rows, err := db.Connection.Query(query, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
users := []User{}
|
|
for rows.Next() {
|
|
var u User
|
|
err = rows.Scan(&u.Id, &u.NormalName, &u.Name, &u.Reference, &u.IsAdmin, &u.IsLive)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
users = append(users, u)
|
|
}
|
|
err = rows.Err()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return users, nil
|
|
}
|
|
|
|
func queryOneUser(query string, args ...any) (*User, error) {
|
|
users, err := queryManyUsers(query, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(users) < 1 {
|
|
return nil, nil
|
|
}
|
|
return &users[0], nil
|
|
}
|
|
|
|
func getUserByName(username string) (*User, error) {
|
|
username = normalize.Name(username)
|
|
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM v_user WHERE name = ?"
|
|
return queryOneUser(stmt, username)
|
|
}
|
|
|
|
func createUser(name string, passHash []byte, isAdmin bool) (*User, error) {
|
|
username := normalize.Name(name)
|
|
stmt := "INSERT INTO user (name, display_name, reference, password_hash, is_admin) VALUES (?, ?, ?, ?, ?)"
|
|
reference, err := uuid.NewRandom()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Failed to generate reference: %w", err)
|
|
}
|
|
result, err := db.Connection.Exec(stmt, username, name, reference, passHash, isAdmin)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Failed to execute query: %w", err)
|
|
}
|
|
id, err := result.LastInsertId()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Failed to get last insert id: %w", err)
|
|
}
|
|
user := User{
|
|
Id: fmt.Sprintf("%d", id),
|
|
Name: name,
|
|
}
|
|
return &user, nil
|
|
}
|
|
|
|
func (u *User) getPassHash() ([]byte, error) {
|
|
stmt := "SELECT password_hash FROM v_user WHERE id = ?"
|
|
var passHash string
|
|
err := db.Connection.QueryRow(stmt, u.Id).Scan(&passHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []byte(passHash), nil
|
|
}
|
|
|
|
func getUserByReference(reference string) (*User, error) {
|
|
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM v_user WHERE reference = ?"
|
|
return queryOneUser(stmt, reference)
|
|
}
|
|
|
|
func getUserById(id string) (*User, error) {
|
|
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM v_user WHERE id = ?"
|
|
return queryOneUser(stmt, id)
|
|
}
|
|
|
|
func hasUsers() (bool, error) {
|
|
stmt := "SELECT COUNT(id) FROM v_user LIMIT 1"
|
|
var userCount uint
|
|
err := db.Connection.QueryRow(stmt).Scan(&userCount)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return userCount > 0, nil
|
|
}
|
|
|
|
func (*Admin) ListUsers() ([]User, error) {
|
|
stmt := "SELECT id, name, display_name, reference, is_admin, is_live FROM user"
|
|
return queryManyUsers(stmt)
|
|
}
|
|
|
|
func (*Admin) GetUser(id string) (*User, error) {
|
|
return getUserById(id)
|
|
}
|
|
|
|
func GetUserByReference(reference string) (*User, error) {
|
|
return getUserByReference(reference)
|
|
}
|
|
|
|
func (u *User) GetTodo() ([]Wish, error) {
|
|
stmt := "SELECT wish.id, wish.name, wish.sent, recipient.name, recipient.reference FROM wish JOIN v_user AS user ON wish.claimant_id = user.id JOIN v_user AS recipient ON wish.recipient_id = recipient.id WHERE user.id = ? ORDER BY wish.sent ASC, wish.name"
|
|
rows, err := db.Connection.Query(stmt, u.Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
wishes := []Wish{}
|
|
for rows.Next() {
|
|
var id string
|
|
var name string
|
|
var sent bool
|
|
var recipientName string
|
|
var recipientRef string
|
|
_ = rows.Scan(&id, &name, &sent, &recipientName, &recipientRef)
|
|
wish := Wish{
|
|
Id: id,
|
|
Name: name,
|
|
Sent: sent,
|
|
RecipientName: recipientName,
|
|
RecipientRef: recipientRef,
|
|
}
|
|
wishes = append(wishes, wish)
|
|
}
|
|
err = rows.Err()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return wishes, nil
|
|
}
|
|
|
|
func (u *Admin) UserSetLive(userReference string, setting bool) error {
|
|
query := "UPDATE user SET is_live = ? WHERE reference = ?"
|
|
_, err := db.Connection.Exec(query, setting, userReference)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// u.IsLive = setting
|
|
return err
|
|
}
|