Landed the topic list page (no topics yet, so appearances are deceiving)
This commit is contained in:
+160
-1
@@ -9,8 +9,13 @@
|
||||
// The database package contains database management and storage logic.
|
||||
package database
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Topic is the top-level structure detailing topics.
|
||||
type Topic struct {
|
||||
TopicId int32 `db:"topicid"`
|
||||
ConfId int32 `db:"confid"`
|
||||
@@ -25,6 +30,7 @@ type Topic struct {
|
||||
Name string `db:"name"`
|
||||
}
|
||||
|
||||
// TopicSettings contains per-user settings for topics, including the "last read" message pointer.
|
||||
type TopicSettings struct {
|
||||
TopicId int32 `db:"topicid"`
|
||||
Uid int32 `db:"uid"`
|
||||
@@ -34,3 +40,156 @@ type TopicSettings struct {
|
||||
LastPost *time.Time `db:"last_post"`
|
||||
Subscribe bool `db:"subscribe"`
|
||||
}
|
||||
|
||||
// TopicSummary is a smaller data structure that gets topic information to create the topic list display.
|
||||
type TopicSummary struct {
|
||||
TopicID int32
|
||||
Number int16
|
||||
Name string
|
||||
Unread int32
|
||||
Total int32
|
||||
LastUpdate time.Time
|
||||
Frozen bool
|
||||
Archived bool
|
||||
Subscribed bool
|
||||
}
|
||||
|
||||
// View and sort constants for AmListTopics.
|
||||
const (
|
||||
TopicViewAll = 0
|
||||
TopicViewNew = 1
|
||||
TopicViewActive = 2
|
||||
TopicViewAllVisible = 3
|
||||
TopicViewHidden = 4
|
||||
TopicViewArchive = 5
|
||||
|
||||
TopicSortID = 0
|
||||
TopicSortNumber = 1
|
||||
TopicSortName = 2
|
||||
TopicSortUnread = 3
|
||||
TopicSortTotal = 4
|
||||
TopicSortDate = 5
|
||||
)
|
||||
|
||||
/* AmListTopics produces a list of topic summary information according to specific options.
|
||||
* Parameters:
|
||||
* confid - The ID of the conference to list topics in.
|
||||
* uid - The UID of the user to consider the settings of.
|
||||
* viewOption - One of the following constants:
|
||||
* TopicViewAll - List all topics.
|
||||
* TopicViewNew - List only visible topics with new messages.
|
||||
* TopicViewActive - List only visible topics, with "active" ones coming first.
|
||||
* TopicViewAllVisible - List only visible topics.
|
||||
* TopicViewHidden - List only hidden topics (including archived ones).
|
||||
* TopicViewArchive - List only archived, non-hidden topics.
|
||||
* sortOption - One of the following constants:
|
||||
* TopicSortID - Sort by topic ID.
|
||||
* TopicSortNumber - Sort by topic number in the conference. May be negated to sort in reverse order.
|
||||
* TopicSortName - Sort by topic name. May be negated to sort in reverse order.
|
||||
* TopicSortUnread - Sort by number of unread messages. May be negated to sort in reverse order.
|
||||
* TopicSortTotal - Sort by total number of messages. May be negated to sort in reverse order.
|
||||
* TopicSortDate - Sort by last topic update date. May be negated to sort in reverse order.
|
||||
* ignoreSticky - If false, sticky topics will precede nonsticky ones; if true, stickiness is ignored.
|
||||
* Returns:
|
||||
* List of TopicSummary pointers.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmListTopics(confid int32, uid int32, viewOption int, sortOption int, ignoreSticky bool) ([]*TopicSummary, error) {
|
||||
// Decode the viewOption into a WHERE clause.
|
||||
var whereClause string
|
||||
switch viewOption {
|
||||
case TopicViewAll:
|
||||
whereClause = ""
|
||||
case TopicViewNew:
|
||||
tail := "t.top_message > IFNULL(s.last_message,-1)"
|
||||
if !ignoreSticky {
|
||||
tail = "(t.sticky = 1 OR " + tail + ")"
|
||||
}
|
||||
whereClause = "t.archived = 0 AND IFNULL(s.hidden,0) = 0 AND " + tail
|
||||
case TopicViewActive, TopicViewAllVisible:
|
||||
whereClause = "t.archived = 0 AND IFNULL(s.hidden,0) = 0"
|
||||
case TopicViewHidden:
|
||||
whereClause = "IFNULL(s.hidden,0) = 1"
|
||||
case TopicViewArchive:
|
||||
whereClause = "t.archived = 1 AND IFNULL(s.hidden,0) = 0"
|
||||
default:
|
||||
return nil, errors.New("invalid view option specified")
|
||||
}
|
||||
|
||||
// Decode the sortOption into an ORDER BY clause.
|
||||
var reverse bool = false
|
||||
if sortOption < 0 {
|
||||
reverse = true
|
||||
sortOption = -sortOption
|
||||
}
|
||||
var orderByClause string
|
||||
switch sortOption {
|
||||
case TopicSortID:
|
||||
orderByClause = "t.topicid ASC"
|
||||
case TopicSortNumber:
|
||||
if reverse {
|
||||
orderByClause = "t.num DESC"
|
||||
} else {
|
||||
orderByClause = "t.num ASC"
|
||||
}
|
||||
case TopicSortName:
|
||||
if reverse {
|
||||
orderByClause = "t.name DESC, t.num DESC"
|
||||
} else {
|
||||
orderByClause = "t.name ASC, t.num ASC"
|
||||
}
|
||||
case TopicSortUnread:
|
||||
if reverse {
|
||||
orderByClause = "unread ASC, t.num DESC"
|
||||
} else {
|
||||
orderByClause = "unread DESC, t.num ASC"
|
||||
}
|
||||
case TopicSortTotal:
|
||||
if reverse {
|
||||
orderByClause = "total ASC, t.num DESC"
|
||||
} else {
|
||||
orderByClause = "total DESC, t.num ASC"
|
||||
}
|
||||
case TopicSortDate:
|
||||
if reverse {
|
||||
orderByClause = "t.lastupdate ASC, t.num DESC"
|
||||
} else {
|
||||
orderByClause = "t.lastupdate DESC, t.num ASC"
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("invalid sort option specified")
|
||||
}
|
||||
|
||||
// Build the full SQL statement
|
||||
var fullStatement strings.Builder
|
||||
fullStatement.WriteString("SELECT t.topicid, t.num, t.name, (t.top_message - IFNULL(s.last_message,-1)) AS unread, ")
|
||||
fullStatement.WriteString("(t.top_message + 1) AS total, t.lastupdate, t.frozen, t.archived, IFNULL(s.subscribe,0) AS subscribe, ")
|
||||
fullStatement.WriteString("t.sticky, GREATEST(SIGN(t.top_message - IFNULL(s.last_message,-1)),0) AS newflag ")
|
||||
fullStatement.WriteString("FROM topics t LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ? WHERE t.confid = ? ")
|
||||
if whereClause != "" {
|
||||
fullStatement.WriteString("AND ")
|
||||
fullStatement.WriteString(whereClause)
|
||||
}
|
||||
fullStatement.WriteString(" ORDER BY ")
|
||||
if ignoreSticky {
|
||||
fullStatement.WriteString("t.sticky DESC, ")
|
||||
}
|
||||
if viewOption == TopicViewActive {
|
||||
fullStatement.WriteString("newflag DESC, ")
|
||||
}
|
||||
fullStatement.WriteString(orderByClause)
|
||||
|
||||
// Execute and capture results
|
||||
rs, err := amdb.Query(fullStatement.String(), uid, confid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := make([]*TopicSummary, 0)
|
||||
for rs.Next() {
|
||||
var rec TopicSummary
|
||||
rs.Scan(&rec.TopicID, &rec.Number, &rec.Name, &rec.Unread, &rec.Total, &rec.LastUpdate, &rec.Frozen, &rec.Archived,
|
||||
&rec.Subscribed)
|
||||
rc = append(rc, &rec)
|
||||
}
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user