mirror of
https://github.com/zoriya/vex.git
synced 2025-12-06 07:06:09 +00:00
143 lines
3.8 KiB
Go
143 lines
3.8 KiB
Go
package vex
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/lib/pq"
|
|
)
|
|
|
|
type Entry struct {
|
|
Id uuid.UUID `json:"id"`
|
|
Title string `json:"title"`
|
|
Link string `json:"link"`
|
|
Date time.Time `json:"date"`
|
|
Content string `json:"content"`
|
|
Authors []string `json:"authors"`
|
|
FeedId uuid.UUID `json:"feedId"`
|
|
Feed Feed `json:"feed,omitempty"`
|
|
IsRead bool `json:"isRead"`
|
|
IsBookmarked bool `json:"isBookmarked"`
|
|
IsReadLater bool `json:"isReadLater"`
|
|
IsIgnored bool `json:"isIgnored"`
|
|
}
|
|
|
|
type EntryDao struct {
|
|
Id uuid.UUID
|
|
Title string
|
|
Link string
|
|
Date time.Time
|
|
Content string
|
|
Authors pq.StringArray
|
|
FeedId uuid.UUID `db:"feed_id"`
|
|
Feed FeedDao `db:"feed"`
|
|
|
|
EntryId *uuid.UUID `db:"entry_id"`
|
|
UserId *uuid.UUID `db:"user_id"`
|
|
IsRead *bool `db:"is_read"`
|
|
IsBookmarked *bool `db:"is_bookmarked"`
|
|
IsReadLater *bool `db:"is_read_later"`
|
|
IsIgnored *bool `db:"is_ignored"`
|
|
}
|
|
|
|
func OrDefault[T any](val *T) T {
|
|
if val != nil {
|
|
return *val
|
|
}
|
|
var ret T
|
|
return ret
|
|
}
|
|
|
|
func (e *EntryDao) ToEntry() Entry {
|
|
return Entry{
|
|
Id: e.Id,
|
|
Title: e.Title,
|
|
Link: e.Link,
|
|
Date: e.Date,
|
|
Content: e.Content,
|
|
Authors: e.Authors,
|
|
FeedId: e.FeedId,
|
|
Feed: e.Feed.ToFeed(),
|
|
IsRead: OrDefault(e.IsRead),
|
|
IsBookmarked: OrDefault(e.IsBookmarked),
|
|
IsReadLater: OrDefault(e.IsReadLater),
|
|
IsIgnored: OrDefault(e.IsIgnored),
|
|
}
|
|
}
|
|
|
|
type EntryService struct {
|
|
database *sqlx.DB
|
|
}
|
|
|
|
func NewEntryService(db *sqlx.DB) EntryService {
|
|
return EntryService{database: db}
|
|
}
|
|
|
|
func (s EntryService) Add(entries []EntryDao) error {
|
|
_, err := s.database.NamedExec(
|
|
`insert into entries (id, title, link, date, content, authors, feed_id)
|
|
values (:id, :title, :link, :date, :content, :authors, :feed_id)`,
|
|
entries,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (s EntryService) GetEntry(id uuid.UUID, userId uuid.UUID) (Entry, error) {
|
|
var ret EntryDao
|
|
err := s.database.Get(
|
|
&ret,
|
|
`select e.*, s.*,
|
|
f.id as "feed.id", f.name as "feed.name", f.link as "feed.link", f.favicon_url as "feed.favicon_url",
|
|
f.tags as "feed.tags", f.submitter_id as "feed.submitter_id", f.added_date as "feed.added_date"
|
|
from entries as e
|
|
left join entries_users as s on s.entry_id = e.id and s.user_id = $1
|
|
left join feeds as f on f.id = e.feed_id
|
|
where e.id = $2`,
|
|
userId,
|
|
id,
|
|
)
|
|
if err != nil {
|
|
return Entry{}, err
|
|
}
|
|
return ret.ToEntry(), nil
|
|
}
|
|
|
|
func (s EntryService) ListEntries(userId uuid.UUID) ([]Entry, error) {
|
|
ret := []EntryDao{}
|
|
err := s.database.Select(
|
|
&ret,
|
|
`select e.*, s.*,
|
|
f.id as "feed.id", f.name as "feed.name", f.link as "feed.link", f.favicon_url as "feed.favicon_url",
|
|
f.tags as "feed.tags", f.submitter_id as "feed.submitter_id", f.added_date as "feed.added_date"
|
|
from entries as e
|
|
left join entries_users as s on s.entry_id = e.id and s.user_id = $1
|
|
left join feeds as f on f.id = e.feed_id
|
|
order by e.date desc`,
|
|
userId,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Map(ret, func(e EntryDao, _ int) Entry { return e.ToEntry() }), nil
|
|
}
|
|
|
|
type ChangeStatusDao struct {
|
|
Id uuid.UUID
|
|
User uuid.UUID
|
|
IsRead bool `db:"is_read"`
|
|
IsBookmarked bool `db:"is_bookmarked"`
|
|
IsReadLater bool `db:"is_read_later"`
|
|
IsIgnored bool `db:"is_ignored"`
|
|
}
|
|
|
|
func (s EntryService) ChangeStatus(status ChangeStatusDao) error {
|
|
_, err := s.database.NamedExec(
|
|
`insert into entries_users (entry_id, user_id, is_read, is_bookmarked, is_read_later, is_ignored)
|
|
values (:id, :user, :is_read, :is_bookmarked, :is_read_later, :is_ignored)
|
|
on conflict(entry_id, user_id) do update set is_read = :is_read, is_bookmarked = :is_bookmarked, is_read_later = :is_read_later, is_ignored = :is_ignored`,
|
|
status,
|
|
)
|
|
return err
|
|
}
|