gosora/common/relations.go
Azareal c60118e7c4 WIP forum action code. Currently disabled.
Add Http Conn Count tracking.
Move more panel phrases into the panel namespace.
Use a string builder in hookgen.
Use Countf() in a couple of places to eliminate boilerplate.
Reduce prepared stmt boilerplate in forum store with a lambda.
Reduce prepared stmt boilerplate in topic.go with a lambda.
Reduce prepared stmt boilerplate in group.go with a lambda.
Add TestSetCreatedAt method to *Topic.
Add DateOlderThanQ method to *accDeleteBuilder and *accUpdateBuilder.
Add Stmt method to *accUpdateBuilder and *AccSelectBuilder.
Add AccBuilder interface.
Shorten variable names.
Shorten extractPerm name to ep.
Add avatar_visibility setting stub. Implementation coming in a later commit.
Don't set an IP for installer generated posts.

Add counters_perf_tick_row hook.

Add avatar_visibility phrase.
Add avatar_visibility_label phrase.
Rename forums_no_description to forums_no_desc.
Rename panel.forums_create_description_label to panel.forums_create_desc_label.
Rename panel.forums_create_description to panel.forums_create_desc.
Rename panel_forum_description to panel.forum_desc.
Rename panel_forum_description_placeholder to panel.forum_desc_placeholder.
Add panel_debug_http_conns_label phrase.
Add panel.forum_actions_head phrase.
Add panel.forum_actions_create_head phrase.
Add panel.forum_action_run_on_topic_creation phrase.
Add panel.forum_action_run_days_after_topic_creation phrase.
Add panel.forum_action_run_days_after_topic_last_reply phrase.
Add panel.forum_action_action phrase.
Add panel.forum_action_action_delete phrase.
Add panel.forum_action_action_lock phrase.
Add panel.forum_action_action_unlock phrase.
Add panel.forum_action_action_move phrase.
Add panel.forum_action_extra phrase.
Add panel.forum_action_create_button phrase.

You will need to run the patcher / updater for this commit.
2021-04-08 00:23:11 +10:00

144 lines
4.0 KiB
Go

package common
import (
"database/sql"
qgen "github.com/Azareal/Gosora/query_gen"
)
var UserBlocks BlockStore
//var UserFriends FriendStore
type BlockStore interface {
IsBlockedBy(blocker, blockee int) (bool, error)
BulkIsBlockedBy(blockers []int, blockee int) (bool, error)
Add(blocker, blockee int) error
Remove(blocker, blockee int) error
BlockedByOffset(blocker, offset, perPage int) ([]int, error)
BlockedByCount(blocker int) int
}
type DefaultBlockStore struct {
isBlocked *sql.Stmt
add *sql.Stmt
remove *sql.Stmt
blockedBy *sql.Stmt
blockedByCount *sql.Stmt
}
func NewDefaultBlockStore(acc *qgen.Accumulator) (*DefaultBlockStore, error) {
ub := "users_blocks"
return &DefaultBlockStore{
isBlocked: acc.Select(ub).Cols("blocker").Where("blocker=? AND blockedUser=?").Prepare(),
add: acc.Insert(ub).Columns("blocker,blockedUser").Fields("?,?").Prepare(),
remove: acc.Delete(ub).Where("blocker=? AND blockedUser=?").Prepare(),
blockedBy: acc.Select(ub).Columns("blockedUser").Where("blocker=?").Limit("?,?").Prepare(),
blockedByCount: acc.Count(ub).Where("blocker=?").Prepare(),
}, acc.FirstError()
}
func (s *DefaultBlockStore) IsBlockedBy(blocker, blockee int) (bool, error) {
e := s.isBlocked.QueryRow(blocker, blockee).Scan(&blocker)
if e == ErrNoRows {
return false, nil
}
return e == nil, e
}
// TODO: Optimise the query to avoid preparing it on the spot? Maybe, use knowledge of the most common IN() parameter counts?
func (s *DefaultBlockStore) BulkIsBlockedBy(blockers []int, blockee int) (bool, error) {
if len(blockers) == 0 {
return false, nil
}
if len(blockers) == 1 {
return s.IsBlockedBy(blockers[0], blockee)
}
idList, q := inqbuild(blockers)
count, e := qgen.NewAcc().Count("users_blocks").Where("blocker IN(" + q + ") AND blockedUser=?").TotalP(idList...)
if e == ErrNoRows {
return false, nil
}
return count == 0, e
}
func (s *DefaultBlockStore) Add(blocker, blockee int) error {
_, e := s.add.Exec(blocker, blockee)
return e
}
func (s *DefaultBlockStore) Remove(blocker, blockee int) error {
_, e := s.remove.Exec(blocker, blockee)
return e
}
func (s *DefaultBlockStore) BlockedByOffset(blocker, offset, perPage int) (uids []int, err error) {
rows, e := s.blockedBy.Query(blocker, offset, perPage)
if e != nil {
return nil, e
}
defer rows.Close()
for rows.Next() {
var uid int
if e := rows.Scan(&uid); e != nil {
return nil, e
}
uids = append(uids, uid)
}
return uids, rows.Err()
}
func (s *DefaultBlockStore) BlockedByCount(blocker int) (count int) {
e := s.blockedByCount.QueryRow(blocker).Scan(&count)
if e != nil {
LogError(e)
}
return count
}
type FriendInvite struct {
Requester int
Target int
}
type FriendStore interface {
AddInvite(requester, target int) error
Confirm(requester, target int) error
GetOwSentInvites(uid int) ([]FriendInvite, error)
GetOwnRecvInvites(uid int) ([]FriendInvite, error)
}
type DefaultFriendStore struct {
addInvite *sql.Stmt
confirm *sql.Stmt
getOwnSentInvites *sql.Stmt
getOwnRecvInvites *sql.Stmt
}
func NewDefaultFriendStore(acc *qgen.Accumulator) (*DefaultFriendStore, error) {
ufi := "users_friends_invites"
return &DefaultFriendStore{
addInvite: acc.Insert(ufi).Columns("requester,target").Fields("?,?").Prepare(),
confirm: acc.Insert("users_friends").Columns("uid,uid2").Fields("?,?").Prepare(),
getOwnSentInvites: acc.Select(ufi).Cols("requester,target").Where("requester=?").Prepare(),
getOwnRecvInvites: acc.Select(ufi).Cols("requester,target").Where("target=?").Prepare(),
}, acc.FirstError()
}
func (s *DefaultFriendStore) AddInvite(requester, target int) error {
_, e := s.addInvite.Exec(requester, target)
return e
}
func (s *DefaultFriendStore) Confirm(requester, target int) error {
_, e := s.confirm.Exec(requester, target)
return e
}
func (s *DefaultFriendStore) GetOwnSentInvites(uid int) ([]FriendInvite, error) {
return nil, nil
}
func (s *DefaultFriendStore) GetOwnRecvInvites(uid int) ([]FriendInvite, error) {
return nil, nil
}