package database import ( "backend/utils" "fmt" "time" ) type User struct { ID int64 `json:"id"` Username string `json:"username"` Password string `json:"-"` Email string `json:"-"` RegistrationDate time.Time `json:"reg_date" db:"reg_date"` LastSeen time.Time `json:"last_seen" db:"last_seen"` Avatar string `json:"avatar"` IsSuperuser bool `json:"is_superuser" db:"is_superuser"` IsActivated bool `json:"is_activated" db:"is_activated"` GroupID int8 `json:"-" db:"group_id"` Group Group `json:"group"` Cover string `json:"cover"` UseGravatar bool `json:"use_gravatar" db:"use_gravatar"` Theme string `json:"theme"` IsBanned bool `json:"is_banned" db:"is_banned"` } type UserSettings struct { UseGravatar bool `json:"use_gravatar" db:"use_gravatar"` Avatar string `json:"avatar"` Theme string `json:"theme"` } type UserNovels struct { UserID int64 `json:"user_id" db:"user_id" sql:"REFERENCES users(id)"` NovelID int16 `json:"novel_id" db:"novel_id" sql:"REFERENCES novels(id)"` Mark int8 `json:"mark"` Status string `json:"status"` } type UserNovelWithInfo struct { UserNovels Novel } var ( ErrNotAuthorized = fmt.Errorf("%s", "not authorized") ) func FetchUsers() ([]*User, error) { var users = make([]*User, 0) err := Database.Select(&users, "select * from users limit 20;") for _, user := range users { if user.UseGravatar { user.Avatar = GetUserGravatar(user.Email) } err = Database.Get(&user.Group, `select * from groups where id = $1;`, user.GroupID) } return users, err } func FetchUser(id int) (*User, error) { user := new(User) err := Database.Get(user, `select users.* from users where users.id = $1;`, id) if err == nil { if user.UseGravatar { user.Avatar = GetUserGravatar(user.Email) } err = Database.Get(&user.Group, `select * from groups where id = $1;`, user.GroupID) } return user, err } func UpdateUser(user *User) (*User, error) { var u = &User{} rows, err := Database.NamedQuery(`update users set avatar=:avatar, username=:username, is_activated=:is_activated, use_gravatar=:use_gravatar where id=:id returning *;`, user) if rows != nil && rows.Next() { _ = rows.StructScan(u) if u.UseGravatar { u.Avatar = GetUserGravatar(u.Email) } } return u, err } func UpdatePassword(id int, password string) error { _, err := Database.Exec("update users set password=$1 where id=$2;", password, id) return err } func FetchUserByLogin(login string) (*User, error) { user := new(User) err := Database.Get(user, `select * from users where username = $1 or email = $1;`, login) if err == nil { if user.UseGravatar { user.Avatar = GetUserGravatar(user.Email) } err = Database.Get(&user.Group, `select * from groups where id = $1;`, user.GroupID) } return user, err } func FetchUserNovels(id int) ([]*UserNovelWithInfo, error) { var novels = make([]*UserNovelWithInfo, 0) err := Database.Select(&novels, `select novels.*, user_novel.* from user_novel inner join novels on (novels.id = user_novel.novel_id) where user_id = $1;`, id) return novels, err } func CreateUserNovel(novelData *UserNovels) (*UserNovels, error) { var novel = &UserNovels{} rows, err := Database.NamedQuery(`insert into user_novel(user_id, novel_id, mark, status) VALUES (:user_id, :novel_id, :mark, :status) returning *;`, novelData) if rows != nil && rows.Next() { _ = rows.StructScan(novel) } return novel, err } func FetchUserNovel(userId int, novelId int) (*UserNovels, error) { var novel = &UserNovels{} err := Database.Get(novel, `select user_novel.* from user_novel where user_id = $1 and novel_id = $2;`, userId, novelId) return novel, err } func UpdateUserNovel(novel *UserNovels) (*UserNovels, error) { var updatedNovel = &UserNovels{} rows, err := Database.NamedQuery(`update user_novel set mark=:mark, status=:status where user_id=:user_id and novel_id=:novel_id returning *;`, novel) _, _ = Database.Exec(`update novels set rating=avg_novel($1) where id=$1;`, novel.NovelID) if rows != nil && rows.Next() { _ = rows.StructScan(updatedNovel) } return updatedNovel, err } func DeleteUserNovel(userId int, novelId int) error { _, err := Database.Exec("delete from user_novel where user_id = $1 and novel_id = $2;", userId, novelId) return err } func FetchUserNovelsComments(id int) ([]CommentNovel, error) { var comments = make([]CommentNovel, 0) err := Database.Select(&comments, `select * from novel_comment where user_id = $1;`, id) return comments, err } func CreateUser(username string, password string, email string) (*User, error) { var user = &User{} var currentTime = time.Now() err := Database.Get(user, "insert into users(username, password, email, reg_date, last_seen) VALUES ($1, $2, $3, $4, $4) returning *;", username, password, email, currentTime) return user, err } func ActivateUser(id int) (*User, error) { var user = &User{} err := Database.Get(user, `update users set is_activated=true where id=$1 returning *;`, id) return user, err } func GetUserGravatar(email string) string { return fmt.Sprintf("https://www.gravatar.com/avatar/%s", utils.MD5(email)) } // Settings func FetchUserSettings(id uint64) (*UserSettings, error) { settings := new(UserSettings) err := Database.Get(settings, "select use_gravatar, avatar, theme from users where id=$1;", id) return settings, err } func UpdateUserSettings(id uint64, settings *UserSettings) (*User, error) { user := new(User) err := Database.Get(user, "update users set use_gravatar=$2, avatar=$3, theme=$4 where id=$1 returning *;", id, settings.UseGravatar, settings.Avatar, settings.Theme) return user, err }