diff --git a/conference.go b/conference.go index 1e8d8c8..c719e5c 100644 --- a/conference.go +++ b/conference.go @@ -266,7 +266,36 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) { return "framed_template", "new_topic.jet", nil } if ctxt.FormFieldIsSet("post1") { + // start by checking the title and pseud + checker, err := htmlcheck.AmNewHTMLChecker("post-pseud") + if err != nil { + return ui.ErrorPage(ctxt, err) + } + checker.Append(ctxt.FormField("title")) + checker.Finish() + topicName, _ := checker.Value() + checker.Reset() + checker.Append(ctxt.FormField("pseud")) + checker.Finish() + zeroPostPseud, _ := checker.Value() + // now check the post data itself + checker, err = htmlcheck.AmNewHTMLChecker("post-body") + if err != nil { + return ui.ErrorPage(ctxt, err) + } + checker.SetContext("PostLinkDecoderContext", database.AmCreatePostLinkContext(comm.Alias, ctxt.URLParam("cid"), conf.TopTopic+1)) + checker.Append(ctxt.FormField("pb")) + checker.Finish() + zeroPost, _ := checker.Value() + lines, _ := checker.Lines() + + // Add the topic! + topic, err := database.AmNewTopic(conf, ctxt.CurrentUser(), topicName, zeroPostPseud, zeroPost, int32(lines)) + if err != nil { + return ui.ErrorPage(ctxt, err) + } + _ = topic // TODO } return ui.ErrorPage(ctxt, errors.New("invalid button clicked on form")) diff --git a/database/topic.go b/database/topic.go index aab4f33..668fcd9 100644 --- a/database/topic.go +++ b/database/topic.go @@ -11,6 +11,7 @@ package database import ( "errors" + "fmt" "strings" "time" ) @@ -54,6 +55,21 @@ type TopicSummary struct { Subscribed bool } +func AmGetTopic(topicId int32) (*Topic, error) { + var dbdata []Topic + err := amdb.Select(&dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId) + if err != nil { + return nil, err + } + if len(dbdata) == 0 { + return nil, fmt.Errorf("topic %d not found", topicId) + } + if len(dbdata) > 1 { + return nil, fmt.Errorf("AmGetTopic(%d): too many responses (%d)", topicId, len(dbdata)) + } + return &(dbdata[0]), nil +} + // View and sort constants for AmListTopics. const ( TopicViewAll = 0 @@ -193,3 +209,74 @@ func AmListTopics(confid int32, uid int32, viewOption int, sortOption int, ignor } return rc, nil } + +func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string, zeroPost string, zeroPostLines int32) (*Topic, error) { + unlock := true + amdb.Exec("LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts WRITE, postdata WRITE;") + defer func() { + if unlock { + amdb.Exec("UNLOCK TABLES;") + } + }() + + // Insert the new topic into the database. + conf.Mutex.Lock() + rs, err := amdb.Exec("INSERT INTO topics (confid, num, creator_uid, createdate, lastupdate, name) VALUES (?, ?, ?, NOW(), NOW(), ?)", + conf.ConfId, conf.TopTopic+1, user.Uid, title) + if err != nil { + conf.Mutex.Unlock() + return nil, err + } + xid, err := rs.LastInsertId() + if err != nil { + conf.Mutex.Unlock() + return nil, err + } + topic, err := AmGetTopic(int32(xid)) + if err != nil { + conf.Mutex.Unlock() + return nil, err + } + + // Update the conference to set the last update and top topic. + _, err = amdb.Exec("UPDATE confs SET lastupdate = ?, top_topic = ? WHERE confid = ?", topic.CreateDate, conf.TopTopic+1, conf.ConfId) + if err != nil { + conf.Mutex.Unlock() + return nil, err + } + conf.TopTopic++ + conf.LastUpdate = &topic.CreateDate + conf.Mutex.Unlock() + + // Add the "header record" for the first post. + rs, err = amdb.Exec("INSERT INTO posts (topicid, num, linecount, creator_uid, posted, pseud) VALUES (?, 0, ?, ?, ?, ?)", + topic.TopicId, zeroPostLines, user.Uid, topic.CreateDate, zeroPostPseud) + if err != nil { + return nil, err + } + xid, err = rs.LastInsertId() + if err != nil { + return nil, err + } + newPostId := int32(xid) + + // Add the post data. + _, err = amdb.Exec("INSERT INTO postdata (postid, data) VALUES (?, ?)", newPostId, zeroPost) + if err != nil { + return nil, err + } + + // Add a new topic settings record for the user, too. + _, err = amdb.Exec("INSERT INTO topicsettings (topicid, uid, last_post) VALUES (?, ?, ?)", + topic.TopicId, user.Uid, topic.CreateDate) + if err != nil { + return nil, err + } + + amdb.Exec("UNLOCK TABLES;") + unlock = false + + // TODO: audit record + + return topic, nil +}