49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package sql
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.sleepycat.moe/sam/mercury/internal/database"
|
|
"github.com/keegancsmith/sqlf"
|
|
"github.com/oklog/ulid/v2"
|
|
)
|
|
|
|
// TimelineStore is the interface to post timelines in the database.
|
|
type TimelineStore struct {
|
|
q Querier
|
|
}
|
|
|
|
// NewTimelineStore creates a new TimelineStore instance.
|
|
func NewTimelineStore(q Querier) *TimelineStore {
|
|
return &TimelineStore{q: q}
|
|
}
|
|
|
|
type TimelinePost struct {
|
|
database.Post
|
|
database.Blog
|
|
}
|
|
|
|
func (s *TimelineStore) Home(ctx context.Context, accountID ulid.ULID, limit int, before, after *ulid.ULID) ([]TimelinePost, error) {
|
|
q := sqlf.Sprintf("SELECT p.*, b.account_id, b.name, b.domain FROM posts p JOIN blogs b ON b.id = p.blog_id")
|
|
|
|
q = sqlf.Sprintf("%v WHERE (blog_id IN (%s) OR blog_id IN (%s))", q,
|
|
sqlf.Sprintf("SELECT id FROM blogs WHERE account_id = %s", accountID),
|
|
sqlf.Sprintf("SELECT blog_id FROM account_follows WHERE account_id = %s", accountID))
|
|
|
|
if before != nil {
|
|
q = sqlf.Sprintf("%v AND id < %s", q, *before)
|
|
}
|
|
if after != nil {
|
|
q = sqlf.Sprintf("%v AND id > %s", q, *after)
|
|
}
|
|
|
|
q = sqlf.Sprintf("%v AND (visibility != %s OR (b.account_id = %s OR %s IN (%s)))", q, database.DirectVisibility, accountID, accountID,
|
|
sqlf.Sprintf("SELECT account_id FROM blogs WHERE id IN (SELECT blog_id FROM post_recipients WHERE post_id = p.id)"))
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
limit = 100
|
|
}
|
|
q = sqlf.Sprintf("%v ORDER BY id DESC LIMIT %d", q, limit)
|
|
|
|
return Select[TimelinePost](ctx, s.q, q)
|
|
}
|