migration to chi
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package database
|
||||
|
||||
type Character struct {
|
||||
ID int32 `json:"id"`
|
||||
OriginalName string `db:"original_name" json:"original_name"`
|
||||
LocalizedName string `db:"localized_name" json:"localized_name"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
Main bool `json:"main"`
|
||||
}
|
||||
|
||||
func FetchCharacters() ([]*Character, error) {
|
||||
var characters = make([]*Character, 0)
|
||||
err := Database.Select(&characters, `select * from characters;`)
|
||||
return characters, err
|
||||
}
|
||||
|
||||
func FetchCharacter(id int) (*Character, error) {
|
||||
var char = &Character{}
|
||||
err := Database.Get(char, `select * from characters where id=$1;`, id)
|
||||
return char, err
|
||||
}
|
||||
func UpdateCharacter(character *Character) (*Character, error) {
|
||||
rows, err := Database.NamedQuery("update characters set original_name=:original_name, localized_name=:localized_name, description=:description, image=:image where id=:id returning *;", character)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
char := new(Character)
|
||||
if rows.Next() {
|
||||
err = rows.StructScan(char)
|
||||
}
|
||||
return char, err
|
||||
}
|
||||
func DeleteCharacter(id int) error {
|
||||
_, err := Database.Exec("delete from characters where id=$1;", id)
|
||||
return err
|
||||
}
|
||||
|
||||
func FetchCharacterNovels(id int) ([]Novel, error) {
|
||||
var novels = make([]Novel, 0)
|
||||
err := Database.Select(&novels, `select id, original_name, localized_name, coalesce(n.image, '') as image from character_novel join novels n on (n.id=character_novel.novel_id) where character_id=$1;`, id)
|
||||
return novels, err
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package database
|
||||
|
||||
type Club struct {
|
||||
ID uint16 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Owner int `json:"-"`
|
||||
IsPrivate bool `json:"is_private" db:"is_private"`
|
||||
}
|
||||
|
||||
func GetClubs(userId int) ([]*Club, error) {
|
||||
clubs := make([]*Club, 0)
|
||||
err := Database.Select(&clubs, "select clubs.* from clubs join club_member cm on clubs.id = cm.club_id where not is_private or cm.user_id=$1;", userId)
|
||||
return clubs, err
|
||||
}
|
||||
|
||||
func GetClub(id int, userId uint64) (*Club, error) {
|
||||
club := new(Club)
|
||||
err := Database.Get(club, "select clubs.* from clubs join club_member cm on clubs.id = cm.club_id where club_id=$1 and (not is_private or cm.user_id=$2);", id, userId)
|
||||
return club, err
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Database *sqlx.DB
|
||||
|
||||
func ConnectToDB() {
|
||||
var err error
|
||||
|
||||
host := os.Getenv("DB_HOST")
|
||||
user := os.Getenv("DB_USER")
|
||||
password := os.Getenv("DB_PASSWORD")
|
||||
name := os.Getenv("DB_NAME")
|
||||
|
||||
url := fmt.Sprintf("host=%s port=5432 user=%s password=%s dbname=%s sslmode=disable", host, user, password, name)
|
||||
Database, err = sqlx.Open("postgres", url)
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
log.Printf("Connected to DB with name %v as %v on %v\n", name, user, host)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package database
|
||||
|
||||
import "time"
|
||||
|
||||
type Game struct {
|
||||
ID int32 `json:"id"`
|
||||
OriginalName string `json:"original_name" db:"original_name"`
|
||||
LocalizedName string `json:"localized_name" db:"localized_name"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
ReleaseDate time.Time `json:"release_date" db:"release_date"`
|
||||
}
|
||||
|
||||
func FetchGame(id int32) (Game, error) {
|
||||
var game Game
|
||||
err := Database.Get(&game, "select * from games where id = $1 limit 1;", id)
|
||||
return game, err
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package database
|
||||
|
||||
// TODO
|
||||
type Genre struct {
|
||||
ID int16 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
LocalizedName string `json:"localized_name" db:"localized_name"`
|
||||
}
|
||||
|
||||
func FetchGenres() ([]*Genre, error) {
|
||||
var genres = make([]*Genre, 0)
|
||||
err := Database.Select(&genres, "select * from genres;")
|
||||
return genres, err
|
||||
}
|
||||
|
||||
func FetchGenre(id int) (*Genre, error) {
|
||||
var genre = &Genre{}
|
||||
err := Database.Get(genre, "select * from genres where id = $1;", id)
|
||||
return genre, err
|
||||
}
|
||||
|
||||
func FetchGenreNovels(id int) ([]*Novel, error) {
|
||||
var novels = make([]*Novel, 0)
|
||||
err := Database.Select(&novels, "select novels.* from novel_genre join novels on (novel_genre.novel_id = novels.id) where genre_id = $1;", id)
|
||||
return novels, err
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package database
|
||||
|
||||
type Group struct {
|
||||
ID uint8 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
MaxAvatarSize int `json:"max_avatar_size" db:"max_ava_size"`
|
||||
MaxAvaWeight int64 `json:"max_avatar_weight" db:"max_ava_weight"`
|
||||
IsSuperuser bool `json:"is_superuser" db:"is_superuser"`
|
||||
Permissions string `json:"permissions"`
|
||||
}
|
||||
|
||||
func GetGroups() ([]*Group, error) {
|
||||
var groups = make([]*Group, 0)
|
||||
err := Database.Select(&groups, "select * from groups;")
|
||||
return groups, err
|
||||
}
|
||||
|
||||
func GetGroup(id int) (*Group, error) {
|
||||
var group = &Group{}
|
||||
err := Database.Get(group, "select * from groups where id=$1;", id)
|
||||
return group, err
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Post struct {
|
||||
ID uint16 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
ShortPost string `json:"short_post" db:"short_post"`
|
||||
FullPost string `json:"full_post" db:"full_post"`
|
||||
Date time.Time `json:"date"`
|
||||
AuthorID uint64 `json:"author_id" db:"author_id" sql:"REFERENCES users(id)"`
|
||||
Author string `json:"author"`
|
||||
}
|
||||
|
||||
func FetchTotalNews() (int, error) {
|
||||
count := 0
|
||||
err := Database.Get(&count, `select count("news") from news;`)
|
||||
return count, err
|
||||
}
|
||||
func FetchNews(offset, limit int) ([]Post, error) {
|
||||
news := make([]Post, 0)
|
||||
err := Database.Select(&news, "select news.*, u.username as author from news inner join users u on news.author_id = u.id offset $1 limit $2;", offset, limit)
|
||||
return news, err
|
||||
}
|
||||
func CreatePost(post *Post) (*Post, error) {
|
||||
destPost := new(Post)
|
||||
r, err := Database.NamedQuery("insert into news (title, short_post, full_post, author_id) values (:title, :short_post, :full_post, :author_id) returning *;", post)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if r.Next() {
|
||||
err = r.StructScan(destPost)
|
||||
}
|
||||
return destPost, err
|
||||
}
|
||||
|
||||
func FetchPost(id int) (*Post, error) {
|
||||
post := &Post{}
|
||||
err := Database.Get(post, "select news.*, u.username as author from news inner join users u on news.author_id = u.id where news.id = $1;", id)
|
||||
return post, err
|
||||
}
|
||||
func UpdatePost(post *Post) error {
|
||||
_, err := Database.NamedExec("update news set title=:title, short_post=:short_post, full_post=:full_post where id=:id;", post)
|
||||
return err
|
||||
}
|
||||
func DeletePost(id int) error {
|
||||
_, err := Database.Exec("delete from news where id=$1;", id)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"backend/utils"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Novel struct {
|
||||
ID int32 `json:"id"`
|
||||
OriginalName string `db:"original_name" json:"original_name"`
|
||||
LocalizedName string `db:"localized_name" json:"localized_name"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
Rating float32 `json:"rating"`
|
||||
ReleaseDate time.Time `json:"release_date" db:"release_date"`
|
||||
Duration uint64 `json:"duration"`
|
||||
ExitStatus string `json:"exit_status" db:"exit_status"`
|
||||
IsDemo bool `json:"is_demo" db:"is_demo"`
|
||||
Platforms string `json:"platforms"`
|
||||
Genres []Genre `json:"genres" ignore:"1"`
|
||||
Links []NovelLink `json:"links" ignore:"1"`
|
||||
Walkthrough string `json:"walkthrough"`
|
||||
RatingAll []RatingAll `json:"rating_all" ignore:"1"`
|
||||
StatusAll []StatusAll `json:"status_all" ignore:"1"`
|
||||
IsNSFW bool `json:"is_nsfw" db:"is_nsfw"`
|
||||
}
|
||||
|
||||
type ShortNovel struct {
|
||||
ID int32 `json:"id"`
|
||||
OriginalName string `db:"original_name" json:"original_name"`
|
||||
LocalizedName string `db:"localized_name" json:"localized_name"`
|
||||
Description string `json:"-"`
|
||||
Image string `json:"image"`
|
||||
Rating float32 `json:"rating"`
|
||||
ReleaseDate time.Time `json:"release_date" db:"release_date"`
|
||||
Duration uint64 `json:"-"`
|
||||
ExitStatus string `json:"exit_status" db:"exit_status"`
|
||||
IsDemo bool `json:"is_demo" db:"is_demo"`
|
||||
Platforms string `json:"-"`
|
||||
Genres []Genre `json:"genres" ignore:"1"`
|
||||
Links []NovelLink `json:"-" ignore:"1"`
|
||||
Walkthrough string `json:"-"`
|
||||
RatingAll []RatingAll `json:"rating_all" ignore:"1"`
|
||||
IsNSFW bool `json:"is_nsfw" db:"is_nsfw"`
|
||||
}
|
||||
|
||||
type CommentNovel struct {
|
||||
ID int32 `json:"id" db:"id"`
|
||||
UserID int64 `json:"user_id" db:"user_id" sql:"REFERENCES users(id)"`
|
||||
NovelID int16 `json:"novel_id" db:"novel_id" sql:"REFERENCES novels(id)"`
|
||||
Text string `json:"text" db:"text"`
|
||||
}
|
||||
|
||||
type NovelLink struct {
|
||||
NovelID int32 `json:"novel_id" db:"novel_id"`
|
||||
Name string `json:"name"`
|
||||
Link string `json:"link"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type RatingAll struct {
|
||||
Mark int `json:"mark"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type StatusAll struct {
|
||||
Status string `json:"status"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func FetchNovels(orderBy string) ([]*ShortNovel, error) {
|
||||
var novels = make([]*ShortNovel, 0)
|
||||
err := Database.Select(&novels, fmt.Sprintf("select id, original_name, localized_name, image, rating, release_date from novels order by %v desc;", orderBy))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx := Database.MustBegin()
|
||||
for _, novel := range novels {
|
||||
novel.Genres = make([]Genre, 0)
|
||||
err = tx.Select(&novel.Genres, "select g.* from novel_genre join genres g on g.id = novel_genre.genre_id where novel_id=$1;", novel.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err = tx.Commit()
|
||||
return novels, err
|
||||
}
|
||||
|
||||
func FetchNovel(id int) (*Novel, error) {
|
||||
novel := new(Novel)
|
||||
err := Database.Get(novel, `select * from novels where id = $1;`, id)
|
||||
if err != nil {
|
||||
return novel, err
|
||||
}
|
||||
|
||||
novel.Genres = make([]Genre, 0)
|
||||
err = Database.Select(&novel.Genres, `select genres.* from novel_genre join genres on (novel_genre.genre_id = genres.id) where novel_id = $1`, id)
|
||||
if err != nil {
|
||||
return novel, err
|
||||
}
|
||||
|
||||
novel.RatingAll = make([]RatingAll, 0)
|
||||
err = Database.Select(&novel.RatingAll, `select mark, count(mark) from user_novel where novel_id=$1 and mark > 0 group by mark;`, id)
|
||||
if err != nil {
|
||||
return novel, err
|
||||
}
|
||||
|
||||
novel.StatusAll = make([]StatusAll, 0)
|
||||
err = Database.Select(&novel.StatusAll, `select status, count(status) from user_novel where novel_id=$1 group by status;`, id)
|
||||
if err != nil {
|
||||
return novel, err
|
||||
}
|
||||
|
||||
novel.Links = make([]NovelLink, 0)
|
||||
err = Database.Select(&novel.Links, "select * from novel_link where novel_id=$1;", novel.ID)
|
||||
return novel, err
|
||||
}
|
||||
func UpdateNovel(novel *Novel) (*Novel, error) {
|
||||
var newNovel = new(Novel)
|
||||
setPart := ""
|
||||
setPartList := make([]string, 0)
|
||||
for _, i := range utils.GetStructAndNamedForDatabase(newNovel) {
|
||||
setPartList = append(setPartList, i[0]+"="+i[1])
|
||||
}
|
||||
setPart = strings.Join(setPartList, ",")
|
||||
rows, err := Database.NamedQuery(fmt.Sprintf(`update novels set %s where id=:id returning *;`, setPart), novel)
|
||||
if err != nil {
|
||||
return newNovel, err
|
||||
}
|
||||
err = UpdateNovelGenres(int(novel.ID), novel.Genres)
|
||||
if err != nil {
|
||||
return newNovel, err
|
||||
}
|
||||
rows.Next()
|
||||
err = rows.StructScan(&newNovel)
|
||||
if err != nil {
|
||||
return newNovel, err
|
||||
}
|
||||
genres, err := FetchNovelGenres(int(novel.ID))
|
||||
newNovel.Genres = genres
|
||||
|
||||
return newNovel, err
|
||||
}
|
||||
func UpdateNovelGenres(novelId int, genres []Genre) error {
|
||||
_, err := Database.Exec("delete from novel_genre where novel_id=$1;", novelId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := Database.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, genre := range genres {
|
||||
_, err = tx.Exec("insert into novel_genre values ($1, $2);", genre.ID, novelId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func UpdateNovelCover(novelId int, url string) error {
|
||||
_, err := Database.Exec("update novels set image=$1 where id=$2;", url, novelId)
|
||||
return err
|
||||
}
|
||||
|
||||
func CreateNovel(novelData *Novel) (Novel, error) {
|
||||
var novel Novel
|
||||
rows, err := Database.NamedQuery(`insert into novels (original_name, localized_name, image, description, is_demo) values (:original_name, :localized_name, :image, :description, :is_demo) returning *;`, novelData)
|
||||
if rows != nil && rows.Next() {
|
||||
_ = rows.StructScan(&novel)
|
||||
}
|
||||
return novel, err
|
||||
}
|
||||
func DeleteNovel(id int) error {
|
||||
_, err := Database.Exec("delete from novels where id = $1;", id)
|
||||
return err
|
||||
}
|
||||
func SearchNovels(query string) ([]ShortNovel, error) {
|
||||
novels := make([]ShortNovel, 0)
|
||||
err := Database.Select(&novels, "select * from search_novel($1) order by rating desc;", query)
|
||||
if err != nil {
|
||||
return novels, err
|
||||
}
|
||||
tx := Database.MustBegin()
|
||||
for _, novel := range novels {
|
||||
novel.Genres = make([]Genre, 0)
|
||||
err = tx.Select(&novel.Genres, "select g.* from novel_genre join genres g on g.id = novel_genre.genre_id where novel_id=$1;", novel.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err = tx.Commit()
|
||||
return novels, err
|
||||
}
|
||||
|
||||
func FetchNovelComments(id int) ([]CommentNovel, error) {
|
||||
var comments = make([]CommentNovel, 0)
|
||||
err := Database.Select(&comments, `select * from novel_comment where novel_id = $1;`, id)
|
||||
return comments, err
|
||||
}
|
||||
func AddNovelComment(commentData CommentNovel) (CommentNovel, error) {
|
||||
var comment CommentNovel
|
||||
rows, err := Database.NamedQuery(`insert into novel_comment(user_id, novel_id, text) values (:user_id, :novel_id, :text) returning *;`, commentData)
|
||||
if rows != nil && rows.Next() {
|
||||
_ = rows.StructScan(&comment)
|
||||
}
|
||||
return comment, err
|
||||
}
|
||||
|
||||
func FetchNovelCharacters(id int) ([]Character, error) {
|
||||
var characters = make([]Character, 0)
|
||||
err := Database.Select(&characters, `select characters.*, character_novel.main from character_novel join characters on (characters.id=character_novel.character_id) where novel_id=$1;`, id)
|
||||
return characters, err
|
||||
}
|
||||
|
||||
func FetchNovelGenres(id int) ([]Genre, error) {
|
||||
var genres = make([]Genre, 0)
|
||||
err := Database.Select(&genres, `select genres.* from novel_genre join genres on (novel_genre.genre_id = genres.id) where novel_id = $1`, id)
|
||||
return genres, err
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package database
|
||||
|
||||
type App struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Secret string `json:"-"`
|
||||
IsVerified bool `json:"is_verified" db:"is_verified"`
|
||||
}
|
||||
|
||||
func FetchApp(id int) (*App, error) {
|
||||
var app = &App{}
|
||||
err := Database.Get(app, "select * from apps where id=$1;", id)
|
||||
return app, err
|
||||
}
|
||||
|
||||
func FetchApps() ([]*App, error) {
|
||||
var apps = make([]*App, 0)
|
||||
err := Database.Select(&apps, "select * from apps;")
|
||||
return apps, err
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user