Cascade deletes for attachments properly when deleting a topic or deleting all of a user's posts.
Eliminate some allocs for maxAgeYear in ShowAttachment. Split DeleteAttachment out of deleteAttachment for reuse elsewhere.
This commit is contained in:
parent
dc19773100
commit
da26a29597
|
@ -4,8 +4,9 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Attachments AttachmentStore
|
var Attachments AttachmentStore
|
||||||
|
@ -26,9 +27,9 @@ type AttachmentStore interface {
|
||||||
Get(id int) (*MiniAttachment, error)
|
Get(id int) (*MiniAttachment, error)
|
||||||
MiniGetList(originTable string, originID int) (alist []*MiniAttachment, err error)
|
MiniGetList(originTable string, originID int) (alist []*MiniAttachment, err error)
|
||||||
BulkMiniGetList(originTable string, ids []int) (amap map[int][]*MiniAttachment, err error)
|
BulkMiniGetList(originTable string, ids []int) (amap map[int][]*MiniAttachment, err error)
|
||||||
Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path string, extra string) (int, error)
|
Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path, extra string) (int, error)
|
||||||
MoveTo(sectionID int, originID int, originTable string) error
|
MoveTo(sectionID int, originID int, originTable string) error
|
||||||
MoveToByExtra(sectionID int, originTable string, extra string) error
|
MoveToByExtra(sectionID int, originTable, extra string) error
|
||||||
Count() int
|
Count() int
|
||||||
CountIn(originTable string, oid int) int
|
CountIn(originTable string, oid int) int
|
||||||
CountInPath(path string) int
|
CountInPath(path string) int
|
||||||
|
@ -50,7 +51,7 @@ type DefaultAttachmentStore struct {
|
||||||
func NewDefaultAttachmentStore(acc *qgen.Accumulator) (*DefaultAttachmentStore, error) {
|
func NewDefaultAttachmentStore(acc *qgen.Accumulator) (*DefaultAttachmentStore, error) {
|
||||||
a := "attachments"
|
a := "attachments"
|
||||||
return &DefaultAttachmentStore{
|
return &DefaultAttachmentStore{
|
||||||
get: acc.Select(a).Columns("originID, sectionID, uploadedBy, path, extra").Where("attachID = ?").Prepare(),
|
get: acc.Select(a).Columns("originID, sectionID, uploadedBy, path, extra").Where("attachID=?").Prepare(),
|
||||||
getByObj: acc.Select(a).Columns("attachID, sectionID, uploadedBy, path, extra").Where("originTable = ? AND originID = ?").Prepare(),
|
getByObj: acc.Select(a).Columns("attachID, sectionID, uploadedBy, path, extra").Where("originTable = ? AND originID = ?").Prepare(),
|
||||||
add: acc.Insert(a).Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path, extra").Fields("?,?,?,?,?,?,?").Prepare(),
|
add: acc.Insert(a).Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path, extra").Fields("?,?,?,?,?,?,?").Prepare(),
|
||||||
count: acc.Count(a).Prepare(),
|
count: acc.Count(a).Prepare(),
|
||||||
|
@ -58,7 +59,7 @@ func NewDefaultAttachmentStore(acc *qgen.Accumulator) (*DefaultAttachmentStore,
|
||||||
countInPath: acc.Count(a).Where("path = ?").Prepare(),
|
countInPath: acc.Count(a).Where("path = ?").Prepare(),
|
||||||
move: acc.Update(a).Set("sectionID = ?").Where("originID = ? AND originTable = ?").Prepare(),
|
move: acc.Update(a).Set("sectionID = ?").Where("originID = ? AND originTable = ?").Prepare(),
|
||||||
moveByExtra: acc.Update(a).Set("sectionID = ?").Where("originTable = ? AND extra = ?").Prepare(),
|
moveByExtra: acc.Update(a).Set("sectionID = ?").Where("originTable = ? AND extra = ?").Prepare(),
|
||||||
delete: acc.Delete(a).Where("attachID = ?").Prepare(),
|
delete: acc.Delete(a).Where("attachID=?").Prepare(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ func (s *DefaultAttachmentStore) Get(id int) (*MiniAttachment, error) {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultAttachmentStore) Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path string, extra string) (int, error) {
|
func (s *DefaultAttachmentStore) Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path, extra string) (int, error) {
|
||||||
res, err := s.add.Exec(sectionID, sectionTable, originID, originTable, uploadedBy, path, extra)
|
res, err := s.add.Exec(sectionID, sectionTable, originID, originTable, uploadedBy, path, extra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -155,7 +156,7 @@ func (s *DefaultAttachmentStore) MoveTo(sectionID int, originID int, originTable
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultAttachmentStore) MoveToByExtra(sectionID int, originTable string, extra string) error {
|
func (s *DefaultAttachmentStore) MoveToByExtra(sectionID int, originTable, extra string) error {
|
||||||
_, err := s.moveByExtra.Exec(sectionID, originTable, extra)
|
_, err := s.moveByExtra.Exec(sectionID, originTable, extra)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -188,3 +189,25 @@ func (s *DefaultAttachmentStore) Delete(aid int) error {
|
||||||
_, err := s.delete.Exec(aid)
|
_, err := s.delete.Exec(aid)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add a table for the files and lock the file row when performing tasks related to the file
|
||||||
|
func DeleteAttachment(aid int) error {
|
||||||
|
attach, err := Attachments.Get(aid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = Attachments.Delete(aid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
count := Attachments.CountInPath(attach.Path)
|
||||||
|
if count == 0 {
|
||||||
|
err := os.Remove("./attachs/" + attach.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
111
common/topic.go
111
common/topic.go
|
@ -184,25 +184,25 @@ func (t *TopicsRow) Topic() *Topic {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
type TopicStmts struct {
|
type TopicStmts struct {
|
||||||
getRids *sql.Stmt
|
getRids *sql.Stmt
|
||||||
getReplies *sql.Stmt
|
getReplies *sql.Stmt
|
||||||
addReplies *sql.Stmt
|
addReplies *sql.Stmt
|
||||||
updateLastReply *sql.Stmt
|
updateLastReply *sql.Stmt
|
||||||
lock *sql.Stmt
|
lock *sql.Stmt
|
||||||
unlock *sql.Stmt
|
unlock *sql.Stmt
|
||||||
moveTo *sql.Stmt
|
moveTo *sql.Stmt
|
||||||
stick *sql.Stmt
|
stick *sql.Stmt
|
||||||
unstick *sql.Stmt
|
unstick *sql.Stmt
|
||||||
hasLikedTopic *sql.Stmt
|
hasLikedTopic *sql.Stmt
|
||||||
createLike *sql.Stmt
|
createLike *sql.Stmt
|
||||||
addLikesToTopic *sql.Stmt
|
addLikesToTopic *sql.Stmt
|
||||||
delete *sql.Stmt
|
delete *sql.Stmt
|
||||||
deleteLikesForTopic *sql.Stmt
|
deleteLikesForTopic *sql.Stmt
|
||||||
deleteActivity *sql.Stmt
|
deleteActivity *sql.Stmt
|
||||||
deleteActivitySubs *sql.Stmt
|
deleteActivitySubs *sql.Stmt
|
||||||
edit *sql.Stmt
|
edit *sql.Stmt
|
||||||
setPoll *sql.Stmt
|
setPoll *sql.Stmt
|
||||||
createAction *sql.Stmt
|
createAction *sql.Stmt
|
||||||
|
|
||||||
getTopicUser *sql.Stmt // TODO: Can we get rid of this?
|
getTopicUser *sql.Stmt // TODO: Can we get rid of this?
|
||||||
getByReplyID *sql.Stmt
|
getByReplyID *sql.Stmt
|
||||||
|
@ -214,25 +214,25 @@ func init() {
|
||||||
DbInits.Add(func(acc *qgen.Accumulator) error {
|
DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
t := "topics"
|
t := "topics"
|
||||||
topicStmts = TopicStmts{
|
topicStmts = TopicStmts{
|
||||||
getRids: acc.Select("replies").Columns("rid").Where("tid = ?").Orderby("rid ASC").Limit("?,?").Prepare(),
|
getRids: acc.Select("replies").Columns("rid").Where("tid = ?").Orderby("rid ASC").Limit("?,?").Prepare(),
|
||||||
getReplies: acc.SimpleLeftJoin("replies AS r", "users AS u", "r.rid, r.content, r.createdBy, r.createdAt, r.lastEdit, r.lastEditBy, u.avatar, u.name, u.group, u.level, r.ipaddress, r.likeCount, r.attachCount, r.actionType", "r.createdBy = u.uid", "r.tid = ?", "r.rid ASC", "?,?"),
|
getReplies: acc.SimpleLeftJoin("replies AS r", "users AS u", "r.rid, r.content, r.createdBy, r.createdAt, r.lastEdit, r.lastEditBy, u.avatar, u.name, u.group, u.level, r.ipaddress, r.likeCount, r.attachCount, r.actionType", "r.createdBy = u.uid", "r.tid = ?", "r.rid ASC", "?,?"),
|
||||||
addReplies: acc.Update(t).Set("postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()").Where("tid = ?").Prepare(),
|
addReplies: acc.Update(t).Set("postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()").Where("tid = ?").Prepare(),
|
||||||
updateLastReply: acc.Update(t).Set("lastReplyID=?").Where("lastReplyID > ? AND tid = ?").Prepare(),
|
updateLastReply: acc.Update(t).Set("lastReplyID=?").Where("lastReplyID > ? AND tid = ?").Prepare(),
|
||||||
lock: acc.Update(t).Set("is_closed=1").Where("tid=?").Prepare(),
|
lock: acc.Update(t).Set("is_closed=1").Where("tid=?").Prepare(),
|
||||||
unlock: acc.Update(t).Set("is_closed=0").Where("tid=?").Prepare(),
|
unlock: acc.Update(t).Set("is_closed=0").Where("tid=?").Prepare(),
|
||||||
moveTo: acc.Update(t).Set("parentID=?").Where("tid=?").Prepare(),
|
moveTo: acc.Update(t).Set("parentID=?").Where("tid=?").Prepare(),
|
||||||
stick: acc.Update(t).Set("sticky=1").Where("tid=?").Prepare(),
|
stick: acc.Update(t).Set("sticky=1").Where("tid=?").Prepare(),
|
||||||
unstick: acc.Update(t).Set("sticky=0").Where("tid=?").Prepare(),
|
unstick: acc.Update(t).Set("sticky=0").Where("tid=?").Prepare(),
|
||||||
hasLikedTopic: acc.Select("likes").Columns("targetItem").Where("sentBy=? and targetItem=? and targetType='topics'").Prepare(),
|
hasLikedTopic: acc.Select("likes").Columns("targetItem").Where("sentBy=? and targetItem=? and targetType='topics'").Prepare(),
|
||||||
createLike: acc.Insert("likes").Columns("weight, targetItem, targetType, sentBy, createdAt").Fields("?,?,?,?,UTC_TIMESTAMP()").Prepare(),
|
createLike: acc.Insert("likes").Columns("weight, targetItem, targetType, sentBy, createdAt").Fields("?,?,?,?,UTC_TIMESTAMP()").Prepare(),
|
||||||
addLikesToTopic: acc.Update(t).Set("likeCount=likeCount+?").Where("tid = ?").Prepare(),
|
addLikesToTopic: acc.Update(t).Set("likeCount=likeCount+?").Where("tid = ?").Prepare(),
|
||||||
delete: acc.Delete(t).Where("tid=?").Prepare(),
|
delete: acc.Delete(t).Where("tid=?").Prepare(),
|
||||||
deleteLikesForTopic: acc.Delete("likes").Where("targetItem=? AND targetType='topics'").Prepare(),
|
deleteLikesForTopic: acc.Delete("likes").Where("targetItem=? AND targetType='topics'").Prepare(),
|
||||||
deleteActivity: acc.Delete("activity_stream").Where("elementID=? AND elementType='topic'").Prepare(),
|
deleteActivity: acc.Delete("activity_stream").Where("elementID=? AND elementType='topic'").Prepare(),
|
||||||
deleteActivitySubs: acc.Delete("activity_subscriptions").Where("targetID=? AND targetType='topic'").Prepare(),
|
deleteActivitySubs: acc.Delete("activity_subscriptions").Where("targetID=? AND targetType='topic'").Prepare(),
|
||||||
edit: acc.Update(t).Set("title=?,content=?,parsed_content=?").Where("tid=?").Prepare(), // TODO: Only run the content update bits on non-polls, does this matter?
|
edit: acc.Update(t).Set("title=?,content=?,parsed_content=?").Where("tid=?").Prepare(), // TODO: Only run the content update bits on non-polls, does this matter?
|
||||||
setPoll: acc.Update(t).Set("poll=?").Where("tid=? AND poll=0").Prepare(),
|
setPoll: acc.Update(t).Set("poll=?").Where("tid=? AND poll=0").Prepare(),
|
||||||
createAction: acc.Insert("replies").Columns("tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content").Fields("?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''").Prepare(),
|
createAction: acc.Insert("replies").Columns("tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content").Fields("?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''").Prepare(),
|
||||||
|
|
||||||
getTopicUser: acc.SimpleLeftJoin("topics AS t", "users AS u", "t.title, t.content, t.createdBy, t.createdAt, t.lastReplyAt, t.lastReplyBy, t.lastReplyID, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.attachCount,t.poll, u.name, u.avatar, u.group, u.level", "t.createdBy = u.uid", "tid = ?", "", ""),
|
getTopicUser: acc.SimpleLeftJoin("topics AS t", "users AS u", "t.title, t.content, t.createdBy, t.createdAt, t.lastReplyAt, t.lastReplyBy, t.lastReplyID, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.attachCount,t.poll, u.name, u.avatar, u.group, u.level", "t.createdBy = u.uid", "tid = ?", "", ""),
|
||||||
getByReplyID: acc.SimpleLeftJoin("replies AS r", "topics AS t", "t.tid, t.title, t.content, t.createdBy, t.createdAt, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.poll, t.data", "r.tid = t.tid", "rid = ?", "", ""),
|
getByReplyID: acc.SimpleLeftJoin("replies AS r", "topics AS t", "t.tid, t.title, t.content, t.createdBy, t.createdAt, t.is_closed, t.sticky, t.parentID, t.ipaddress, t.views, t.postCount, t.likeCount, t.poll, t.data", "r.tid = t.tid", "rid = ?", "", ""),
|
||||||
|
@ -350,6 +350,35 @@ func handleLikedTopicReplies(tid int) error {
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleTopicAttachments(tid int) error {
|
||||||
|
f := func(stmt *sql.Stmt) error {
|
||||||
|
rows, err := stmt.Query(tid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var aid int
|
||||||
|
err := rows.Scan(&aid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = DeleteAttachment(aid)
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
|
err := f(userStmts.getAttachmentsOfTopic)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return f(userStmts.getAttachmentsOfTopic2)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Use a transaction here
|
// TODO: Use a transaction here
|
||||||
func (t *Topic) Delete() error {
|
func (t *Topic) Delete() error {
|
||||||
creator, err := Users.Get(t.CreatedBy)
|
creator, err := Users.Get(t.CreatedBy)
|
||||||
|
@ -380,6 +409,10 @@ func (t *Topic) Delete() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
err = handleTopicAttachments(t.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
_, err = topicStmts.deleteActivitySubs.Exec(t.ID)
|
_, err = topicStmts.deleteActivitySubs.Exec(t.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -389,7 +422,7 @@ func (t *Topic) Delete() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if t.Poll > 0 {
|
if t.Poll > 0 {
|
||||||
err = (&Poll{ID:t.Poll}).Delete()
|
err = (&Poll{ID: t.Poll}).Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -523,7 +556,7 @@ func (ru *ReplyUser) Init() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Factor TopicUser into a *Topic and *User, as this starting to become overly complicated x.x
|
// TODO: Factor TopicUser into a *Topic and *User, as this starting to become overly complicated x.x
|
||||||
func (t *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*ReplyUser, ogdesc string, err error) {
|
func (t *TopicUser) Replies(offset, pFrag int, user *User) (rlist []*ReplyUser, ogdesc string, err error) {
|
||||||
var likedMap map[int]int
|
var likedMap map[int]int
|
||||||
if user.Liked > 0 {
|
if user.Liked > 0 {
|
||||||
likedMap = make(map[int]int)
|
likedMap = make(map[int]int)
|
||||||
|
|
|
@ -150,6 +150,8 @@ type UserStmts struct {
|
||||||
deleteProfilePosts *sql.Stmt
|
deleteProfilePosts *sql.Stmt
|
||||||
deleteReplyPosts *sql.Stmt
|
deleteReplyPosts *sql.Stmt
|
||||||
getLikedRepliesOfTopic *sql.Stmt
|
getLikedRepliesOfTopic *sql.Stmt
|
||||||
|
getAttachmentsOfTopic *sql.Stmt
|
||||||
|
getAttachmentsOfTopic2 *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
var userStmts UserStmts
|
var userStmts UserStmts
|
||||||
|
@ -191,6 +193,8 @@ func init() {
|
||||||
deleteProfilePosts: acc.Select("users_replies").Columns("rid").Where("createdBy=?").Prepare(),
|
deleteProfilePosts: acc.Select("users_replies").Columns("rid").Where("createdBy=?").Prepare(),
|
||||||
deleteReplyPosts: acc.Select("replies").Columns("rid,tid").Where("createdBy=?").Prepare(),
|
deleteReplyPosts: acc.Select("replies").Columns("rid,tid").Where("createdBy=?").Prepare(),
|
||||||
getLikedRepliesOfTopic: acc.Select("replies").Columns("rid").Where("tid=? AND likeCount>0").Prepare(),
|
getLikedRepliesOfTopic: acc.Select("replies").Columns("rid").Where("tid=? AND likeCount>0").Prepare(),
|
||||||
|
getAttachmentsOfTopic: acc.Select("attachments").Columns("attachID").Where("originID=? AND originTable='topics'").Prepare(),
|
||||||
|
getAttachmentsOfTopic2: acc.Select("attachments").Columns("attachID").Where("extra=? AND originTable='replies'").Prepare(),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
})
|
})
|
||||||
|
@ -356,6 +360,10 @@ func (u *User) DeletePosts() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
err = handleTopicAttachments(tid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
_, err = topicStmts.deleteActivitySubs.Exec(tid)
|
_, err = topicStmts.deleteActivitySubs.Exec(tid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -365,7 +373,7 @@ func (u *User) DeletePosts() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if poll > 0 {
|
if poll > 0 {
|
||||||
err = (&Poll{ID:poll}).Delete()
|
err = (&Poll{ID: poll}).Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,12 @@ package routes
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AttachmentStmts struct {
|
type AttachmentStmts struct {
|
||||||
|
@ -22,12 +21,14 @@ var attachmentStmts AttachmentStmts
|
||||||
func init() {
|
func init() {
|
||||||
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
attachmentStmts = AttachmentStmts{
|
attachmentStmts = AttachmentStmts{
|
||||||
get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Prepare(),
|
get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path=? AND sectionID=? AND sectionTable=?").Prepare(),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var maxAgeYear = "max-age=" + strconv.Itoa(int(c.Year))
|
||||||
|
|
||||||
func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filename string) c.RouteError {
|
func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filename string) c.RouteError {
|
||||||
filename = c.Stripslashes(filename)
|
filename = c.Stripslashes(filename)
|
||||||
ext := filepath.Ext("./attachs/" + filename)
|
ext := filepath.Ext("./attachs/" + filename)
|
||||||
|
@ -61,13 +62,13 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
||||||
} else {
|
} else {
|
||||||
return c.LocalError("Unknown section", w, r, user)
|
return c.LocalError("Unknown section", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if originTable != "topics" && originTable != "replies" {
|
if originTable != "topics" && originTable != "replies" {
|
||||||
return c.LocalError("Unknown origin", w, r, user)
|
return c.LocalError("Unknown origin", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !user.Loggedin {
|
if !user.Loggedin {
|
||||||
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
|
w.Header().Set("Cache-Control", maxAgeYear)
|
||||||
} else {
|
} else {
|
||||||
guest := c.GuestUser
|
guest := c.GuestUser
|
||||||
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sid)
|
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sid)
|
||||||
|
@ -76,7 +77,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
||||||
}
|
}
|
||||||
h := w.Header()
|
h := w.Header()
|
||||||
if guest.Perms.ViewTopic {
|
if guest.Perms.ViewTopic {
|
||||||
h.Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
|
h.Set("Cache-Control", maxAgeYear)
|
||||||
} else {
|
} else {
|
||||||
h.Set("Cache-Control", "private")
|
h.Set("Cache-Control", "private")
|
||||||
}
|
}
|
||||||
|
@ -87,32 +88,12 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a table for the files and lock the file row when performing tasks related to the file
|
|
||||||
func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid int, js bool) c.RouteError {
|
func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid int, js bool) c.RouteError {
|
||||||
attach, err := c.Attachments.Get(aid)
|
err := c.DeleteAttachment(aid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.NotFoundJSQ(w, r, nil, js)
|
return c.NotFoundJSQ(w, r, nil, js)
|
||||||
} else if err != nil {
|
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
|
||||||
}
|
}
|
||||||
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
err = c.Attachments.Delete(aid)
|
|
||||||
if err != nil {
|
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
|
||||||
}
|
|
||||||
|
|
||||||
count := c.Attachments.CountInPath(attach.Path)
|
|
||||||
if err != nil {
|
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
|
||||||
}
|
|
||||||
if count == 0 {
|
|
||||||
err := os.Remove("./attachs/" + attach.Path)
|
|
||||||
if err != nil {
|
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Stop duplicating this code
|
// TODO: Stop duplicating this code
|
||||||
|
|
Loading…
Reference in New Issue