Attachments continue to function after the parent topic is moved now.

Changed the signature of AttachmentStore.Add
Added the MoveTo method to AttachmentStore.
Added the MoveToByExtra method to AttachmentStore.
Don't forget to actually add the pre script for topic_c_edit_post x.x

Added the extra column to the attachments table.

You will need to run the updater / patcher for this commit.
This commit is contained in:
Azareal 2019-04-13 21:54:22 +10:00
parent 6128325696
commit cdb2f0711d
13 changed files with 91 additions and 20 deletions

View File

@ -277,7 +277,7 @@ func createTables(adapter qgen.Adapter) error {
tblColumn{"originTable", "varchar", 200, false, false, "replies"}, tblColumn{"originTable", "varchar", 200, false, false, "replies"},
tblColumn{"uploadedBy", "int", 0, false, false, ""}, // TODO; Make this a foreign key tblColumn{"uploadedBy", "int", 0, false, false, ""}, // TODO; Make this a foreign key
tblColumn{"path", "varchar", 200, false, false, ""}, tblColumn{"path", "varchar", 200, false, false, ""},
//tblColumn{"extra", "varchar", 200, false, false, ""}, tblColumn{"extra", "varchar", 200, false, false, ""},
}, },
[]tblKey{ []tblKey{
tblKey{"attachID", "primary"}, tblKey{"attachID", "primary"},

View File

@ -16,6 +16,7 @@ type MiniAttachment struct {
OriginID int OriginID int
UploadedBy int UploadedBy int
Path string Path string
Extra string
Image bool Image bool
Ext string Ext string
@ -25,7 +26,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) (int, error) Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path string, extra string) (int, error)
MoveTo(sectionID int, originID int, originTable string) error
MoveToByExtra(sectionID int, originTable string, extra string) error
GlobalCount() int GlobalCount() int
CountIn(originTable string, oid int) int CountIn(originTable string, oid int) int
CountInPath(path string) int CountInPath(path string) int
@ -39,18 +42,21 @@ type DefaultAttachmentStore struct {
count *sql.Stmt count *sql.Stmt
countIn *sql.Stmt countIn *sql.Stmt
countInPath *sql.Stmt countInPath *sql.Stmt
move *sql.Stmt
moveByExtra *sql.Stmt
delete *sql.Stmt delete *sql.Stmt
} }
func NewDefaultAttachmentStore() (*DefaultAttachmentStore, error) { func NewDefaultAttachmentStore(acc *qgen.Accumulator) (*DefaultAttachmentStore, error) {
acc := qgen.NewAcc()
return &DefaultAttachmentStore{ return &DefaultAttachmentStore{
get: acc.Select("attachments").Columns("originID, sectionID, uploadedBy, path").Where("attachID = ?").Prepare(), get: acc.Select("attachments").Columns("originID, sectionID, uploadedBy, path, extra").Where("attachID = ?").Prepare(),
getByObj: acc.Select("attachments").Columns("attachID, sectionID, uploadedBy, path").Where("originTable = ? AND originID = ?").Prepare(), getByObj: acc.Select("attachments").Columns("attachID, sectionID, uploadedBy, path, extra").Where("originTable = ? AND originID = ?").Prepare(),
add: acc.Insert("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Fields("?,?,?,?,?,?").Prepare(), add: acc.Insert("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path, extra").Fields("?,?,?,?,?,?,?").Prepare(),
count: acc.Count("attachments").Prepare(), count: acc.Count("attachments").Prepare(),
countIn: acc.Count("attachments").Where("originTable = ? and originID = ?").Prepare(), countIn: acc.Count("attachments").Where("originTable = ? and originID = ?").Prepare(),
countInPath: acc.Count("attachments").Where("path = ?").Prepare(), countInPath: acc.Count("attachments").Where("path = ?").Prepare(),
move: acc.Update("attachments").Set("sectionID = ?").Where("originID = ? AND originTable = ?").Prepare(),
moveByExtra: acc.Update("attachments").Set("sectionID = ?").Where("originTable = ? AND extra = ?").Prepare(),
delete: acc.Delete("attachments").Where("attachID = ?").Prepare(), delete: acc.Delete("attachments").Where("attachID = ?").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }
@ -60,7 +66,7 @@ func (store *DefaultAttachmentStore) MiniGetList(originTable string, originID in
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
attach := &MiniAttachment{OriginID: originID} attach := &MiniAttachment{OriginID: originID}
err := rows.Scan(&attach.ID, &attach.SectionID, &attach.UploadedBy, &attach.Path) err := rows.Scan(&attach.ID, &attach.SectionID, &attach.UploadedBy, &attach.Path, &attach.Extra)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -114,7 +120,7 @@ func (store *DefaultAttachmentStore) BulkMiniGetList(originTable string, ids []i
func (store *DefaultAttachmentStore) Get(id int) (*MiniAttachment, error) { func (store *DefaultAttachmentStore) Get(id int) (*MiniAttachment, error) {
attach := &MiniAttachment{ID: id} attach := &MiniAttachment{ID: id}
err := store.get.QueryRow(id).Scan(&attach.OriginID, &attach.SectionID, &attach.UploadedBy, &attach.Path) err := store.get.QueryRow(id).Scan(&attach.OriginID, &attach.SectionID, &attach.UploadedBy, &attach.Path, &attach.Extra)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -127,8 +133,8 @@ func (store *DefaultAttachmentStore) Get(id int) (*MiniAttachment, error) {
return attach, nil return attach, nil
} }
func (store *DefaultAttachmentStore) Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path string) (int, error) { func (store *DefaultAttachmentStore) Add(sectionID int, sectionTable string, originID int, originTable string, uploadedBy int, path string, extra string) (int, error) {
res, err := store.add.Exec(sectionID, sectionTable, originID, originTable, uploadedBy, path) res, err := store.add.Exec(sectionID, sectionTable, originID, originTable, uploadedBy, path, extra)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -136,6 +142,16 @@ func (store *DefaultAttachmentStore) Add(sectionID int, sectionTable string, ori
return int(lid), err return int(lid), err
} }
func (store *DefaultAttachmentStore) MoveTo(sectionID int, originID int, originTable string) error {
_, err := store.move.Exec(sectionID, originID, originTable)
return err
}
func (store *DefaultAttachmentStore) MoveToByExtra(sectionID int, originTable string, extra string) error {
_, err := store.moveByExtra.Exec(sectionID, originTable, extra)
return err
}
func (store *DefaultAttachmentStore) GlobalCount() (count int) { func (store *DefaultAttachmentStore) GlobalCount() (count int) {
err := store.count.QueryRow().Scan(&count) err := store.count.QueryRow().Scan(&count)
if err != nil { if err != nil {

View File

@ -265,6 +265,7 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
addPreScript("topics_topic") addPreScript("topics_topic")
addPreScript("paginator") addPreScript("paginator")
addPreScript("alert") addPreScript("alert")
addPreScript("topic_c_edit_post")
return header, nil return header, nil
} }

View File

@ -251,8 +251,15 @@ func (topic *Topic) Unlock() (err error) {
func (topic *Topic) MoveTo(destForum int) (err error) { func (topic *Topic) MoveTo(destForum int) (err error) {
_, err = topicStmts.moveTo.Exec(destForum, topic.ID) _, err = topicStmts.moveTo.Exec(destForum, topic.ID)
topic.cacheRemove() topic.cacheRemove()
if err != nil {
return err return err
} }
err = Attachments.MoveTo(destForum, topic.ID, "topics")
if err != nil {
return err
}
return Attachments.MoveToByExtra(destForum, "replies", strconv.Itoa(topic.ID))
}
// TODO: We might want more consistent terminology rather than using stick in some places and pin in others. If you don't understand the difference, there is none, they are one and the same. // TODO: We might want more consistent terminology rather than using stick in some places and pin in others. If you don't understand the difference, there is none, they are one and the same.
func (topic *Topic) Stick() (err error) { func (topic *Topic) Stick() (err error) {

View File

@ -152,7 +152,7 @@ func afterDBInit() (err error) {
if err != nil { if err != nil {
return errors.WithStack(err) return errors.WithStack(err)
} }
common.Attachments, err = common.NewDefaultAttachmentStore() common.Attachments, err = common.NewDefaultAttachmentStore(acc)
if err != nil { if err != nil {
return errors.WithStack(err) return errors.WithStack(err)
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"database/sql"
"strconv" "strconv"
"github.com/Azareal/Gosora/query_gen" "github.com/Azareal/Gosora/query_gen"
@ -28,6 +29,7 @@ func init() {
addPatch(14, patch14) addPatch(14, patch14)
addPatch(15, patch15) addPatch(15, patch15)
addPatch(16, patch16) addPatch(16, patch16)
addPatch(17, patch17)
} }
func patch0(scanner *bufio.Scanner) (err error) { func patch0(scanner *bufio.Scanner) (err error) {
@ -550,3 +552,39 @@ func patch16(scanner *bufio.Scanner) error {
}, nil, }, nil,
)) ))
} }
func patch17(scanner *bufio.Scanner) error {
err := execStmt(qgen.Builder.AddColumn("attachments", tblColumn{"extra", "varchar", 200, false, false, ""}, nil))
if err != nil {
return err
}
err = acc().Select("topics").Cols("tid, parentID").Where("attachCount > 0").Each(func(rows *sql.Rows) error {
var tid, parentID int
err := rows.Scan(&tid, &parentID)
if err != nil {
return err
}
_, err = acc().Update("attachments").Set("sectionID = ?").Where("originTable = 'topics' AND originID = ?").Exec(parentID, tid)
return err
})
if err != nil {
return err
}
return acc().Select("replies").Cols("rid, tid").Where("attachCount > 0").Each(func(rows *sql.Rows) error {
var rid, tid, sectionID int
err := rows.Scan(&rid, &tid)
if err != nil {
return err
}
err = acc().Select("topics").Cols("parentID").Where("tid = ?").QueryRow(tid).Scan(&sectionID)
if err != nil {
return err
}
_, err = acc().Update("attachments").Set("sectionID = ?, extra = ?").Where("originTable = 'replies' AND originID = ?").Exec(sectionID, tid, rid)
return err
})
}

View File

@ -32,7 +32,7 @@ func execStmt(stmt *sql.Stmt, err error) error {
}*/ }*/
func eachUser(handle func(int) error) error { func eachUser(handle func(int) error) error {
err := qgen.NewAcc().Select("users").Each(func(rows *sql.Rows) error { err := qgen.NewAcc().Select("users").Cols("uid").Each(func(rows *sql.Rows) error {
var uid int var uid int
err := rows.Scan(&uid) err := rows.Scan(&uid)
if err != nil { if err != nil {

View File

@ -117,7 +117,7 @@ func deleteAttachment(w http.ResponseWriter, r *http.Request, user common.User,
// TODO: Stop duplicating this code // TODO: Stop duplicating this code
// TODO: Use a transaction here // TODO: Use a transaction here
// TODO: Move this function to neutral ground // TODO: Move this function to neutral ground
func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User, sid int, sectionTable string, oid int, originTable string) (pathMap map[string]string, rerr common.RouteError) { func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User, sid int, sectionTable string, oid int, originTable string, extra string) (pathMap map[string]string, rerr common.RouteError) {
pathMap = make(map[string]string) pathMap = make(map[string]string)
files, rerr := uploadFilesWithHash(w, r, user, "./attachs/") files, rerr := uploadFilesWithHash(w, r, user, "./attachs/")
if rerr != nil { if rerr != nil {
@ -125,7 +125,7 @@ func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User,
} }
for _, filename := range files { for _, filename := range files {
aid, err := common.Attachments.Add(sid, sectionTable, oid, originTable, user.ID, filename) aid, err := common.Attachments.Add(sid, sectionTable, oid, originTable, user.ID, filename, extra)
if err != nil { if err != nil {
return nil, common.InternalError(err, w, r) return nil, common.InternalError(err, w, r)
} }

View File

@ -79,7 +79,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
// Handle the file attachments // Handle the file attachments
// TODO: Stop duplicating this code // TODO: Stop duplicating this code
if user.Perms.UploadFiles { if user.Perms.UploadFiles {
_, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", rid, "replies") _, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", rid, "replies", strconv.Itoa(topic.ID))
if rerr != nil { if rerr != nil {
return rerr return rerr
} }
@ -380,7 +380,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.
} }
// Handle the file attachments // Handle the file attachments
pathMap, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", rid, "replies") pathMap, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", rid, "replies", strconv.Itoa(topic.ID))
if rerr != nil { if rerr != nil {
// TODO: This needs to be a JS error... // TODO: This needs to be a JS error...
return rerr return rerr

View File

@ -258,12 +258,18 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
} }
if user.Perms.EditReply && len(attachQueryList) > 0 { if user.Perms.EditReply && len(attachQueryList) > 0 {
//log.Printf("attachQueryList: %+v\n", attachQueryList)
amap, err := common.Attachments.BulkMiniGetList("replies", attachQueryList) amap, err := common.Attachments.BulkMiniGetList("replies", attachQueryList)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
//log.Printf("amap: %+v\n", amap)
//log.Printf("attachMap: %+v\n", attachMap)
for id, attach := range amap { for id, attach := range amap {
tpage.ItemList[attachMap[id]].Attachments = attach tpage.ItemList[attachMap[id]].Attachments = attach
/*for _, a := range attach {
log.Printf("a: %+v\n", a)
}*/
} }
} }
} }
@ -302,7 +308,7 @@ func AddAttachToTopicSubmit(w http.ResponseWriter, r *http.Request, user common.
} }
// Handle the file attachments // Handle the file attachments
pathMap, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", tid, "topics") pathMap, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", tid, "topics", "")
if rerr != nil { if rerr != nil {
// TODO: This needs to be a JS error... // TODO: This needs to be a JS error...
return rerr return rerr
@ -529,7 +535,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
// Handle the file attachments // Handle the file attachments
if user.Perms.UploadFiles { if user.Perms.UploadFiles {
_, rerr := uploadAttachment(w, r, user, fid, "forums", tid, "topics") _, rerr := uploadAttachment(w, r, user, fid, "forums", tid, "topics", "")
if rerr != nil { if rerr != nil {
return rerr return rerr
} }

View File

@ -6,5 +6,6 @@ CREATE TABLE [attachments] (
[originTable] nvarchar (200) DEFAULT 'replies' not null, [originTable] nvarchar (200) DEFAULT 'replies' not null,
[uploadedBy] int not null, [uploadedBy] int not null,
[path] nvarchar (200) not null, [path] nvarchar (200) not null,
[extra] nvarchar (200) not null,
primary key([attachID]) primary key([attachID])
); );

View File

@ -6,5 +6,6 @@ CREATE TABLE `attachments` (
`originTable` varchar(200) DEFAULT 'replies' not null, `originTable` varchar(200) DEFAULT 'replies' not null,
`uploadedBy` int not null, `uploadedBy` int not null,
`path` varchar(200) not null, `path` varchar(200) not null,
`extra` varchar(200) not null,
primary key(`attachID`) primary key(`attachID`)
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; ) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;

View File

@ -6,5 +6,6 @@ CREATE TABLE "attachments" (
`originTable` varchar (200) DEFAULT 'replies' not null, `originTable` varchar (200) DEFAULT 'replies' not null,
`uploadedBy` int not null, `uploadedBy` int not null,
`path` varchar (200) not null, `path` varchar (200) not null,
`extra` varchar (200) not null,
primary key(`attachID`) primary key(`attachID`)
); );