completed the Scan() error handling
This commit is contained in:
@@ -367,6 +367,7 @@ func breakRange(topic *database.Topic, into []int32, param string, sep string) e
|
||||
return nil
|
||||
}
|
||||
|
||||
// templateExtractUserName extracts the user name from the post.
|
||||
func templateExtractUserName(args jet.Arguments) reflect.Value {
|
||||
rc := "<<ERROR>>"
|
||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||
@@ -380,6 +381,7 @@ func templateExtractUserName(args jet.Arguments) reflect.Value {
|
||||
return reflect.ValueOf(rc)
|
||||
}
|
||||
|
||||
// templatePostText gets the text of a post.
|
||||
func templatePostText(args jet.Arguments) reflect.Value {
|
||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
|
||||
@@ -391,6 +393,7 @@ func templatePostText(args jet.Arguments) reflect.Value {
|
||||
return reflect.ValueOf(rc)
|
||||
}
|
||||
|
||||
// templateOverrideLine creates the "override line" for a post, that is, what gets displayed in place of the post text.
|
||||
func templateOverrideLine(args jet.Arguments) reflect.Value {
|
||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
|
||||
@@ -416,6 +419,7 @@ func templateOverrideLine(args jet.Arguments) reflect.Value {
|
||||
return reflect.ValueOf(rc)
|
||||
}
|
||||
|
||||
// templateOverrideLink creates the "override link" for a post, which can make the override line a hyperlink.
|
||||
func templateOverrideLink(args jet.Arguments) reflect.Value {
|
||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||
root := args.Get(1).Convert(reflect.TypeFor[string]()).String()
|
||||
@@ -426,6 +430,14 @@ func templateOverrideLink(args jet.Arguments) reflect.Value {
|
||||
return reflect.ValueOf(rc)
|
||||
}
|
||||
|
||||
/* ReadPosts displays posts in a topic.
|
||||
* Parameters:
|
||||
* ctxt - The AmContext for the request.
|
||||
* Returns:
|
||||
* Command string dictating what to be rendered.
|
||||
* Data as a parameter for the command string.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
||||
// If we need to reset a topic's last read count (as with "Next & Keep New"), spin the task off.
|
||||
if ctxt.HasParameter("rst") {
|
||||
|
||||
+7
-14
@@ -72,13 +72,11 @@ func loadCategories(ctx context.Context) error {
|
||||
return errors.New("internal error loading categories")
|
||||
}
|
||||
var ncats int32
|
||||
err = rs.Scan(&ncats)
|
||||
if err != nil {
|
||||
if err = rs.Scan(&ncats); err != nil {
|
||||
return err
|
||||
}
|
||||
allCategories = make([]Category, 0, ncats)
|
||||
err = amdb.SelectContext(ctx, &allCategories, "SELECT * FROM refcategory ORDER BY parent, name")
|
||||
if err != nil {
|
||||
if err = amdb.SelectContext(ctx, &allCategories, "SELECT * FROM refcategory ORDER BY parent, name"); err != nil {
|
||||
return err
|
||||
}
|
||||
for i, c := range allCategories {
|
||||
@@ -104,8 +102,7 @@ func AmGetCategory(ctx context.Context, catid int32) (*Category, error) {
|
||||
if !ok {
|
||||
return nil, errors.New("category feature not supported")
|
||||
}
|
||||
err = loadCategories(ctx)
|
||||
if err != nil {
|
||||
if err = loadCategories(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := categoryIdMap[catid]
|
||||
@@ -136,8 +133,7 @@ func AmGetCategoryHierarchy(ctx context.Context, catid int32) ([]*Category, erro
|
||||
if !ok {
|
||||
return nil, errors.New("category feature not supported")
|
||||
}
|
||||
err = loadCategories(ctx)
|
||||
if err != nil {
|
||||
if err = loadCategories(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// walk all the way to the "root" (parent = -1)
|
||||
@@ -175,8 +171,7 @@ func AmGetSubCategories(ctx context.Context, catid int32) ([]*Category, error) {
|
||||
if !ok {
|
||||
return nil, errors.New("category feature not supported")
|
||||
}
|
||||
err = loadCategories(ctx)
|
||||
if err != nil {
|
||||
if err = loadCategories(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := make([]*Category, 0)
|
||||
@@ -247,8 +242,7 @@ func AmSearchCategories(ctx context.Context, oper int, term string, offset int,
|
||||
return nil, -1, errors.New("internal error getting category total")
|
||||
}
|
||||
var total int
|
||||
err = rs.Scan(&total)
|
||||
if err != nil {
|
||||
if err = rs.Scan(&total); err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
if total == 0 {
|
||||
@@ -265,8 +259,7 @@ func AmSearchCategories(ctx context.Context, oper int, term string, offset int,
|
||||
rc := make([]*Category, 0, min(max, 1000))
|
||||
for rs.Next() {
|
||||
var catid int32
|
||||
err = rs.Scan(&catid)
|
||||
if err == nil {
|
||||
if err = rs.Scan(&catid); err == nil {
|
||||
c, err := AmGetCategory(ctx, catid)
|
||||
if err == nil {
|
||||
rc = append(rc, c)
|
||||
|
||||
+34
-40
@@ -220,8 +220,7 @@ func (c *Community) Membership(ctx context.Context, u *User) (bool, bool, uint16
|
||||
if rs.Next() {
|
||||
var locked bool
|
||||
var level uint16
|
||||
err = rs.Scan(&locked, &level)
|
||||
if err == nil {
|
||||
if err = rs.Scan(&locked, &level); err == nil {
|
||||
memberCache.Add(key, &memberCacheData{isMember: true, locked: locked, level: level})
|
||||
return true, locked, level, nil
|
||||
}
|
||||
@@ -247,8 +246,7 @@ func (c *Community) MemberCount(ctx context.Context, hidden bool) (int, error) {
|
||||
}
|
||||
if rs.Next() {
|
||||
var rc int
|
||||
err = rs.Scan(&rc)
|
||||
if err == nil {
|
||||
if err = rs.Scan(&rc); err == nil {
|
||||
return rc, nil
|
||||
} else {
|
||||
return -1, err
|
||||
@@ -325,8 +323,7 @@ func (c *Community) ListMembers(ctx context.Context, field int, oper int, term s
|
||||
return nil, -1, errors.New("internal error getting member count")
|
||||
}
|
||||
var total int
|
||||
err = rs.Scan(&total)
|
||||
if err == nil {
|
||||
if err = rs.Scan(&total); err == nil {
|
||||
if offset > 0 {
|
||||
rs, err = amdb.QueryContext(ctx, `SELECT m.uid FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
||||
AND u.contactid = c.contactid`+q+" ORDER BY u.username LIMIT ? OFFSET ?", c.Id, max, offset)
|
||||
@@ -341,12 +338,13 @@ func (c *Community) ListMembers(ctx context.Context, field int, oper int, term s
|
||||
rc := make([]*User, 0, min(max, 10000))
|
||||
for rs.Next() {
|
||||
var uid int32
|
||||
rs.Scan(&uid)
|
||||
if err = rs.Scan(&uid); err == nil {
|
||||
u, err := AmGetUser(ctx, uid)
|
||||
if err == nil {
|
||||
rc = append(rc, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc, total, nil
|
||||
}
|
||||
|
||||
@@ -390,8 +388,7 @@ func (c *Community) SetMembership(ctx context.Context, u *User, level uint16, lo
|
||||
if rs.Next() {
|
||||
var oldLevel uint16
|
||||
var lockStatus bool
|
||||
err = rs.Scan(&oldLevel, &lockStatus)
|
||||
if err != nil {
|
||||
if err = rs.Scan(&oldLevel, &lockStatus); err != nil {
|
||||
return err
|
||||
}
|
||||
if level != oldLevel || lockStatus != locked {
|
||||
@@ -409,14 +406,12 @@ func (c *Community) SetMembership(ctx context.Context, u *User, level uint16, lo
|
||||
return err
|
||||
}
|
||||
stuffMembership(c.Id, u.Uid, true, locked, level)
|
||||
err = AmOnUserJoinCommunityServices(ctx, tx, c, u)
|
||||
if err != nil {
|
||||
if err = AmOnUserJoinCommunityServices(ctx, tx, c, u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err := c.TouchUpdateTx(ctx, tx)
|
||||
if err == nil {
|
||||
if err := c.TouchUpdateTx(ctx, tx); err == nil {
|
||||
ar := AmNewAudit(AuditCommunitySetMembership, personUID, ipaddr, fmt.Sprintf("cid=%d", c.Id),
|
||||
fmt.Sprintf("uid=%d", u.Uid), fmt.Sprintf("level=%d", level))
|
||||
AmStoreAudit(ar)
|
||||
@@ -556,10 +551,11 @@ func (c *Community) Touch(ctx context.Context) error {
|
||||
if err == nil {
|
||||
rs.Next()
|
||||
var na time.Time
|
||||
rs.Scan(&na)
|
||||
if err = rs.Scan(&na); err == nil {
|
||||
c.LastAccess = &na
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -573,11 +569,12 @@ func (c *Community) TouchUpdateTx(ctx context.Context, tx *sqlx.Tx) error {
|
||||
if err != nil {
|
||||
rs.Next()
|
||||
var na, nu time.Time
|
||||
rs.Scan(&na, &nu)
|
||||
if err = rs.Scan(&na, &nu); err == nil {
|
||||
c.LastAccess = &na
|
||||
c.LastUpdate = &nu
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -608,8 +605,7 @@ func AmGetCommunity(ctx context.Context, id int32) (*Community, error) {
|
||||
rc, ok := communityCache.Get(id)
|
||||
if !ok {
|
||||
var dbdata []Community
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -638,8 +634,7 @@ func AmGetCommunityTx(ctx context.Context, tx *sqlx.Tx, id int32) (*Community, e
|
||||
rc, ok := communityCache.Get(id)
|
||||
if !ok {
|
||||
var dbdata []Community
|
||||
err := tx.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id)
|
||||
if err != nil {
|
||||
if err := tx.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -666,8 +661,9 @@ func AmGetCommunityByAlias(ctx context.Context, alias string) (*Community, error
|
||||
if err == nil {
|
||||
if rs.Next() {
|
||||
var cid int32
|
||||
rs.Scan(&cid)
|
||||
if err = rs.Scan(&cid); err == nil {
|
||||
return AmGetCommunity(ctx, cid)
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -689,8 +685,9 @@ func AmGetCommunityByAliasTx(ctx context.Context, tx *sqlx.Tx, alias string) (*C
|
||||
if err == nil {
|
||||
if rs.Next() {
|
||||
var cid int32
|
||||
rs.Scan(&cid)
|
||||
if err = rs.Scan(&cid); err == nil {
|
||||
return AmGetCommunityTx(ctx, tx, cid)
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -768,7 +765,7 @@ func AmGetCommunityAccessLevel(ctx context.Context, uid int32, commid int32) (ui
|
||||
if err == nil {
|
||||
defer rows.Close()
|
||||
if rows.Next() {
|
||||
rows.Scan(&rc)
|
||||
err = rows.Scan(&rc)
|
||||
}
|
||||
}
|
||||
return rc, err
|
||||
@@ -785,8 +782,7 @@ func AmGetCommunityAccessLevel(ctx context.Context, uid int32, commid int32) (ui
|
||||
func AmAutoJoinCommunities(ctx context.Context, tx *sqlx.Tx, user *User) error {
|
||||
// get list of current communities
|
||||
var current []int32 = make([]int32, 0)
|
||||
err := tx.SelectContext(ctx, ¤t, "SELECT commid FROM commmember WHERE uid = ?", user.Uid)
|
||||
if err != nil {
|
||||
if err := tx.SelectContext(ctx, ¤t, "SELECT commid FROM commmember WHERE uid = ?", user.Uid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -799,8 +795,7 @@ func AmAutoJoinCommunities(ctx context.Context, tx *sqlx.Tx, user *User) error {
|
||||
for rows.Next() {
|
||||
var cid int32
|
||||
var lock bool
|
||||
err = rows.Scan(&cid, &lock)
|
||||
if err != nil {
|
||||
if err = rows.Scan(&cid, &lock); err != nil {
|
||||
break
|
||||
}
|
||||
if !slices.Contains(current, cid) {
|
||||
@@ -825,8 +820,7 @@ func internalGetCommProp(ctx context.Context, cid int32, ndx int32) (*CommunityP
|
||||
rc, ok := communityPropCache.Get(key)
|
||||
if !ok {
|
||||
var dbdata []CommunityProperties
|
||||
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx)
|
||||
if err != nil {
|
||||
if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -961,13 +955,11 @@ func AmCreateCommunity(ctx context.Context, name string, alias string, hostUid i
|
||||
stuffMembership(comm.Id, hostUid, true, true, AmDefaultRole("Community.Creator").Level())
|
||||
|
||||
// Establish the community services.
|
||||
err = AmEstablishCommunityServices(ctx, tx, comm)
|
||||
if err != nil {
|
||||
if err = AmEstablishCommunityServices(ctx, tx, comm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
@@ -1005,9 +997,9 @@ func AmGetCommunitiesForCategory(ctx context.Context, catid int32, offset int, m
|
||||
return nil, -1, errors.New("internal error getting total match count")
|
||||
}
|
||||
var total int
|
||||
rs.Scan(&total)
|
||||
if total == 0 {
|
||||
return make([]*Community, 0), 0, nil // short-circuit return
|
||||
err = rs.Scan(&total)
|
||||
if err != nil || total == 0 {
|
||||
return make([]*Community, 0), 0, err // short-circuit return
|
||||
}
|
||||
if showAll {
|
||||
if offset > 0 {
|
||||
@@ -1030,12 +1022,13 @@ func AmGetCommunitiesForCategory(ctx context.Context, catid int32, offset int, m
|
||||
rc := make([]*Community, 0, min(max, 10000))
|
||||
for rs.Next() {
|
||||
var commid int32
|
||||
rs.Scan(&commid)
|
||||
if err = rs.Scan(&commid); err == nil {
|
||||
c, err := AmGetCommunity(ctx, commid)
|
||||
if err == nil {
|
||||
rc = append(rc, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc, total, nil
|
||||
}
|
||||
|
||||
@@ -1097,9 +1090,9 @@ func AmSearchCommunities(ctx context.Context, field int, oper int, term string,
|
||||
return nil, -1, errors.New("internal error getting count")
|
||||
}
|
||||
var total int
|
||||
rs.Scan(&total)
|
||||
if total == 0 {
|
||||
return make([]*Community, 0), 0, nil // short-circuit return
|
||||
err = rs.Scan(&total)
|
||||
if err != nil || total == 0 {
|
||||
return make([]*Community, 0), 0, err // short-circuit return
|
||||
}
|
||||
if offset > 0 {
|
||||
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities "+q+" ORDER BY commname LIMIT ? OFFSET ?", max, offset)
|
||||
@@ -1112,11 +1105,12 @@ func AmSearchCommunities(ctx context.Context, field int, oper int, term string,
|
||||
rc := make([]*Community, 0, min(max, 10000))
|
||||
for rs.Next() {
|
||||
var commid int32
|
||||
rs.Scan(&commid)
|
||||
if err = rs.Scan(&commid); err == nil {
|
||||
c, err := AmGetCommunity(ctx, commid)
|
||||
if err == nil {
|
||||
rc = append(rc, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc, total, nil
|
||||
}
|
||||
|
||||
+22
-11
@@ -101,12 +101,13 @@ func (c *Conference) Hosts(ctx context.Context) ([]*User, error) {
|
||||
rc := make([]*User, 0, 5)
|
||||
for rs.Next() {
|
||||
var uid int32
|
||||
rs.Scan(&uid)
|
||||
if err = rs.Scan(&uid); err == nil {
|
||||
u, err := AmGetUser(ctx, uid)
|
||||
if err == nil {
|
||||
rc = append(rc, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
@@ -122,12 +123,15 @@ func (c *Conference) Membership(ctx context.Context, u *User) (bool, uint16, err
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
rc := false
|
||||
if rs.Next() {
|
||||
rc = true
|
||||
var level uint16
|
||||
rs.Scan(&level)
|
||||
return true, level, nil
|
||||
if err = rs.Scan(&level); err == nil {
|
||||
return rc, level, nil
|
||||
}
|
||||
return false, 0, nil
|
||||
}
|
||||
return rc, 0, err
|
||||
}
|
||||
|
||||
/* TestPermission is shorthand that tests if a user has a permission with respect to the conference.
|
||||
@@ -162,8 +166,7 @@ func (c *Conference) TestPermission(perm string, level uint16) bool {
|
||||
// Settings returns the settings for a user.
|
||||
func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings, error) {
|
||||
var dbdata []ConferenceSettings
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM confsettings WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM confsettings WHERE confid = ? AND uid = ?", c.ConfId, u.Uid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -250,8 +253,7 @@ func AmGetConference(ctx context.Context, id int32) (*Conference, error) {
|
||||
rc, ok := conferenceCache.Get(id)
|
||||
if !ok {
|
||||
var dbdata []Conference
|
||||
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from confs where confid = ?", id)
|
||||
if err != nil {
|
||||
if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from confs where confid = ?", id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -286,7 +288,9 @@ func AmGetConferenceByAlias(ctx context.Context, alias string) (*Conference, err
|
||||
if !rs.Next() {
|
||||
return nil, fmt.Errorf("alias not found: %s", alias)
|
||||
}
|
||||
rs.Scan(&confid)
|
||||
if err = rs.Scan(&confid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conferenceAliasMap.Store(alias, confid)
|
||||
}
|
||||
return AmGetConference(ctx, confid)
|
||||
@@ -311,7 +315,9 @@ func AmGetConferenceByAliasInCommunity(ctx context.Context, cid int32, alias str
|
||||
return nil, errors.New("conference not found")
|
||||
}
|
||||
var confid int32
|
||||
rs.Scan(&confid)
|
||||
if err = rs.Scan(&confid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return AmGetConference(ctx, confid)
|
||||
}
|
||||
|
||||
@@ -337,10 +343,15 @@ func AmGetCommunityConferences(ctx context.Context, cid int32, showHidden bool)
|
||||
rc := make([]*Conference, 0, 6)
|
||||
for rs.Next() {
|
||||
var confid int32
|
||||
rs.Scan(&confid)
|
||||
if err = rs.Scan(&confid); err == nil {
|
||||
conf, err := AmGetConference(ctx, confid)
|
||||
if err == nil {
|
||||
rc = append(rc, conf)
|
||||
} else {
|
||||
log.Errorf("AmGetCommunityConferences conference error: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Errorf("AmGetCommunityConferences scan error: %v", err)
|
||||
}
|
||||
}
|
||||
return rc, nil
|
||||
|
||||
@@ -57,7 +57,7 @@ func lookupCommunityContact(ctx context.Context, id int32) (int32, error) {
|
||||
rs, err := amdb.QueryContext(ctx, "SELECT contactid FROM contacts WHERE owner_commid = ?", id)
|
||||
if err == nil {
|
||||
if rs.Next() {
|
||||
rs.Scan(&rc)
|
||||
err = rs.Scan(&rc)
|
||||
}
|
||||
}
|
||||
return rc, err
|
||||
@@ -69,7 +69,7 @@ func lookupUserContact(ctx context.Context, uid int32) (int32, error) {
|
||||
rs, err := amdb.QueryContext(ctx, "SELECT contactid FROM contacts WHERE owner_uid = ? AND owner_commid = -1", uid)
|
||||
if err == nil {
|
||||
if rs.Next() {
|
||||
rs.Scan(&rc)
|
||||
err = rs.Scan(&rc)
|
||||
}
|
||||
}
|
||||
return rc, err
|
||||
@@ -191,8 +191,8 @@ func (ci *ContactInfo) Save(ctx context.Context) (bool, error) {
|
||||
if !rs.Next() {
|
||||
return false, errors.New("internal error rereading update timestamp")
|
||||
}
|
||||
rs.Scan(&ci.LastUpdate)
|
||||
return emailChange, nil
|
||||
err = rs.Scan(&ci.LastUpdate)
|
||||
return emailChange, err
|
||||
}
|
||||
|
||||
// Clone makes a copy of the ContactInfo.
|
||||
|
||||
+23
-6
@@ -16,6 +16,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// PostHeader represents the "header" of a post, everything except for its text and attachment.
|
||||
type PostHeader struct {
|
||||
PostId int64 `db:"postid"` // ID of the post
|
||||
Parent int64 `db:"parent"` // ID of parent (unused?)
|
||||
@@ -35,6 +36,7 @@ type PostData struct {
|
||||
Data *string `db:"data"` // actual post data
|
||||
}
|
||||
|
||||
// ErrNoPostData is returned if post data is missing.
|
||||
var ErrNoPostData = errors.New("no post data")
|
||||
|
||||
// IsScribbled returns true if the post has been scribbled, false if not.
|
||||
@@ -61,8 +63,7 @@ func (p *PostHeader) SetAttachment(ctx context.Context, fileName string, mimeTyp
|
||||
// Text returns the text associated with a post.
|
||||
func (p *PostHeader) Text(ctx context.Context) (string, error) {
|
||||
var dbdata []PostData
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM postdata WHERE postid = ?", p.PostId)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM postdata WHERE postid = ?", p.PostId); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(dbdata) > 1 {
|
||||
@@ -74,10 +75,17 @@ func (p *PostHeader) Text(ctx context.Context) (string, error) {
|
||||
return *dbdata[0].Data, nil
|
||||
}
|
||||
|
||||
/* AmGetPost gets a single post from the database by ID.
|
||||
* Parameters:
|
||||
* ctx - Standard Go context value.
|
||||
* postId - ID of the post to retrieve.
|
||||
* Returns:
|
||||
* Pointer to PostHeader for the post, or nil.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmGetPost(ctx context.Context, postId int64) (*PostHeader, error) {
|
||||
var dbdata []PostHeader
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE postid = ?", postId)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE postid = ?", postId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -89,10 +97,19 @@ func AmGetPost(ctx context.Context, postId int64) (*PostHeader, error) {
|
||||
return &(dbdata[0]), nil
|
||||
}
|
||||
|
||||
/* AmGetPostRage gets a range of posts from a topic by post numbers.
|
||||
* Parameters:
|
||||
* ctx - Standard Go context value.
|
||||
* topic - Topic pointer to retrieve posts from.
|
||||
* first - Number of first post to retrieve.
|
||||
* last - Number of last post to retrieve.
|
||||
* Returns:
|
||||
* Array of pointers to PostHeader objects, or nil.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmGetPostRange(ctx context.Context, topic *Topic, first, last int32) ([]*PostHeader, error) {
|
||||
var posts []PostHeader
|
||||
err := amdb.SelectContext(ctx, &posts, "SELECT * FROM posts WHERE topicid = ? AND num >= ? AND num <= ? ORDER BY num", topic.TopicId, first, last)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &posts, "SELECT * FROM posts WHERE topicid = ? AND num >= ? AND num <= ? ORDER BY num", topic.TopicId, first, last); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := make([]*PostHeader, len(posts))
|
||||
|
||||
+8
-10
@@ -144,9 +144,10 @@ func AmGetCommunityServices(ctx context.Context, cid int32) ([]*ServiceDef, erro
|
||||
a := make([]*ServiceDef, 0, len(dom.Services))
|
||||
for rs.Next() {
|
||||
var ndx int16
|
||||
rs.Scan(&ndx)
|
||||
if err = rs.Scan(&ndx); err == nil {
|
||||
a = append(a, dom.byIndex[ndx])
|
||||
}
|
||||
}
|
||||
servicesCache.Add(cid, a)
|
||||
rc = a
|
||||
}
|
||||
@@ -175,9 +176,10 @@ func AmGetCommunityServicesTx(ctx context.Context, tx *sqlx.Tx, cid int32) ([]*S
|
||||
a := make([]*ServiceDef, 0, len(dom.Services))
|
||||
for rs.Next() {
|
||||
var ndx int16
|
||||
rs.Scan(&ndx)
|
||||
if err = rs.Scan(&ndx); err == nil {
|
||||
a = append(a, dom.byIndex[ndx])
|
||||
}
|
||||
}
|
||||
servicesCache.Add(cid, a)
|
||||
rc = a
|
||||
}
|
||||
@@ -209,8 +211,7 @@ func AmEstablishCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Community
|
||||
servicesCache.Add(c.Id, a)
|
||||
servicesCacheMutex.Unlock()
|
||||
for _, svc := range a {
|
||||
err := svc.vtable.OnNewCommunity(ctx, tx, c)
|
||||
if err != nil {
|
||||
if err := svc.vtable.OnNewCommunity(ctx, tx, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -230,8 +231,7 @@ func AmDeleteCommunityServices(ctx context.Context, tx *sqlx.Tx, cid int32) erro
|
||||
arr, err := AmGetCommunityServices(ctx, cid)
|
||||
if err == nil {
|
||||
for _, svc := range arr {
|
||||
err = svc.vtable.OnDeleteCommunity(ctx, tx, cid)
|
||||
if err != nil {
|
||||
if err = svc.vtable.OnDeleteCommunity(ctx, tx, cid); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -258,8 +258,7 @@ func AmOnUserJoinCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Communit
|
||||
arr, err := AmGetCommunityServicesTx(ctx, tx, c.Id)
|
||||
if err == nil {
|
||||
for _, svc := range arr {
|
||||
err = svc.vtable.OnUserJoinCommunity(ctx, tx, c, u)
|
||||
if err != nil {
|
||||
if err = svc.vtable.OnUserJoinCommunity(ctx, tx, c, u); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -280,8 +279,7 @@ func AmOnUserLeaveCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Communi
|
||||
arr, err := AmGetCommunityServicesTx(ctx, tx, c.Id)
|
||||
if err == nil {
|
||||
for _, svc := range arr {
|
||||
err = svc.vtable.OnUserLeaveCommunity(ctx, tx, c, u)
|
||||
if err != nil {
|
||||
if err = svc.vtable.OnUserLeaveCommunity(ctx, tx, c, u); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
+19
-9
@@ -118,8 +118,7 @@ type TopicSummary struct {
|
||||
*/
|
||||
func AmGetTopic(ctx context.Context, topicId int32) (*Topic, error) {
|
||||
var dbdata []Topic
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -142,8 +141,7 @@ func AmGetTopic(ctx context.Context, topicId int32) (*Topic, error) {
|
||||
*/
|
||||
func AmGetTopicTx(ctx context.Context, tx *sqlx.Tx, topicId int32) (*Topic, error) {
|
||||
var dbdata []Topic
|
||||
err := tx.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
||||
if err != nil {
|
||||
if err := tx.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -313,9 +311,8 @@ func AmListTopics(ctx context.Context, confid int32, uid int32, viewOption int,
|
||||
rc := make([]*TopicSummary, 0)
|
||||
for rs.Next() {
|
||||
var rec TopicSummary
|
||||
err = rs.Scan(&rec.TopicID, &rec.Number, &rec.Name, &rec.Unread, &rec.Total, &rec.LastUpdate, &rec.Frozen,
|
||||
&rec.Archived, &rec.Subscribed, &rec.Hidden, &rec.Sticky, &rec.NewFlag)
|
||||
if err != nil {
|
||||
if err = rs.Scan(&rec.TopicID, &rec.Number, &rec.Name, &rec.Unread, &rec.Total, &rec.LastUpdate, &rec.Frozen,
|
||||
&rec.Archived, &rec.Subscribed, &rec.Hidden, &rec.Sticky, &rec.NewFlag); err != nil {
|
||||
log.Errorf("AmListTopics scan error: %v", err)
|
||||
} else {
|
||||
rc = append(rc, &rec)
|
||||
@@ -324,6 +321,20 @@ func AmListTopics(ctx context.Context, confid int32, uid int32, viewOption int,
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
/* AmNewTopic creates a new topic.
|
||||
* Parameters:
|
||||
* ctx - Standard Go context value.
|
||||
* conf - Conference to add the new post.
|
||||
* user - User creating the new topic.
|
||||
* title - The new topic's title.
|
||||
* zeroPostPseud - Pseud for the topic's "zero post" (first post).
|
||||
* zeroPost - Textual data for the zero post.
|
||||
* zeroPostLines - Number of lines of text in zeroPost.
|
||||
* ipaddr - IP address of the user making the topic, for audit purposes.
|
||||
* Returns:
|
||||
* Pointer to the new Topic data structure.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func AmNewTopic(ctx context.Context, conf *Conference, user *User, title string, zeroPostPseud string, zeroPost string,
|
||||
zeroPostLines int32, ipaddr string) (*Topic, error) {
|
||||
var ar *AuditRecord = nil
|
||||
@@ -409,8 +420,7 @@ func AmNewTopic(ctx context.Context, conf *Conference, user *User, title string,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
|
||||
+14
-28
@@ -267,10 +267,8 @@ func (u *User) ConfirmEMailAddress(ctx context.Context, confnum int32, remoteIP
|
||||
if err == nil {
|
||||
u.VerifyEMail = true
|
||||
u.BaseLevel = AmDefaultRole("Global.AfterVerify").Level()
|
||||
err = AmAutoJoinCommunities(ctx, tx, u)
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
if err == nil {
|
||||
if err = AmAutoJoinCommunities(ctx, tx, u); err == nil {
|
||||
if err = tx.Commit(); err == nil {
|
||||
success = true
|
||||
ar = AmNewAudit(AuditVerifyEmailOK, u.Uid, remoteIP)
|
||||
}
|
||||
@@ -354,8 +352,7 @@ func (u *User) Prefs(ctx context.Context) (*UserPrefs, error) {
|
||||
defer u.Mutex.Unlock()
|
||||
if u.prefs == nil {
|
||||
var dbdata []UserPrefs
|
||||
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid)
|
||||
if err != nil {
|
||||
if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) != 1 {
|
||||
@@ -402,8 +399,7 @@ func AmGetUser(ctx context.Context, uid int32) (*User, error) {
|
||||
rc, ok := userCache.Get(uid)
|
||||
if !ok {
|
||||
var dbdata []User
|
||||
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid)
|
||||
if err != nil {
|
||||
if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) > 1 {
|
||||
@@ -431,8 +427,7 @@ func AmGetUserTx(ctx context.Context, tx *sqlx.Tx, uid int32) (*User, error) {
|
||||
rc, ok := userCache.Get(uid)
|
||||
if !ok {
|
||||
var dbdata []User
|
||||
err = tx.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid)
|
||||
if err != nil {
|
||||
if err = tx.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) > 1 {
|
||||
@@ -596,8 +591,7 @@ func AmAuthenticateUser(ctx context.Context, name string, password string, remot
|
||||
}
|
||||
log.Debug("...authenticated")
|
||||
touchUser(ctx, tx, user)
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
@@ -680,8 +674,7 @@ func AmAuthenticateUserByToken(ctx context.Context, authString string, remoteIP
|
||||
}
|
||||
log.Debug("...authenticated")
|
||||
touchUser(ctx, tx, user)
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
@@ -754,8 +747,7 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
|
||||
|
||||
// add user properties
|
||||
props := make([]UserProperties, 0)
|
||||
err = tx.SelectContext(ctx, &props, "SELECT * FROM propuser WHERE uid = ?", anon)
|
||||
if err != nil {
|
||||
if err = tx.SelectContext(ctx, &props, "SELECT * FROM propuser WHERE uid = ?", anon); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, p := range props {
|
||||
@@ -766,8 +758,7 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
|
||||
}
|
||||
|
||||
// add user sideboxes
|
||||
err = copySideboxes(ctx, tx, user.Uid, anon)
|
||||
if err != nil {
|
||||
if err = copySideboxes(ctx, tx, user.Uid, anon); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -775,15 +766,13 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
|
||||
unlock = false
|
||||
|
||||
// auto-join communities
|
||||
err = AmAutoJoinCommunities(ctx, tx, user)
|
||||
if err != nil {
|
||||
if err = AmAutoJoinCommunities(ctx, tx, user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: copy conference hotlists
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success = true
|
||||
@@ -802,8 +791,7 @@ func internalGetProp(ctx context.Context, uid int32, ndx int32) (*UserProperties
|
||||
rc, ok := userPropCache.Get(key)
|
||||
if !ok {
|
||||
var dbdata []UserProperties
|
||||
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx)
|
||||
if err != nil {
|
||||
if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(dbdata) == 0 {
|
||||
@@ -925,8 +913,7 @@ func AmSearchUsers(ctx context.Context, field int, oper int, term string, offset
|
||||
return nil, -1, errors.New("internal error getting count")
|
||||
}
|
||||
var total int
|
||||
err = rs.Scan(&total)
|
||||
if err != nil {
|
||||
if err = rs.Scan(&total); err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
if total == 0 {
|
||||
@@ -945,8 +932,7 @@ func AmSearchUsers(ctx context.Context, field int, oper int, term string, offset
|
||||
rc := make([]*User, 0, min(max, 10000))
|
||||
for rs.Next() {
|
||||
var uid int32
|
||||
err = rs.Scan(&uid)
|
||||
if err == nil {
|
||||
if err = rs.Scan(&uid); err == nil {
|
||||
var u *User
|
||||
u, err = AmGetUser(ctx, uid)
|
||||
if err == nil {
|
||||
|
||||
+14
-9
@@ -14,6 +14,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -304,8 +305,8 @@ func (c *amContext) SaveSession() error {
|
||||
* Parameters:
|
||||
* name = The name of the template to be rendered.
|
||||
* Returns:
|
||||
* Byte array with the rendered data to be output
|
||||
* Standard Go error status
|
||||
* Byte array with the rendered data to be output.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func (c *amContext) SubRender(name string) ([]byte, error) {
|
||||
view, err := views.GetTemplate(name)
|
||||
@@ -314,13 +315,20 @@ func (c *amContext) SubRender(name string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
err = view.Execute(buf, c.VarMap(), c)
|
||||
if err != nil {
|
||||
if err = view.Execute(buf, c.VarMap(), c); err != nil {
|
||||
log.Errorf("template \"%s\" failed subrender exec: %v", name, err)
|
||||
}
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
/* SubRender2 renders a subtemplate to the output, with extra variables to be set.
|
||||
* Parameters:
|
||||
* name = The name of the template to be rendered.
|
||||
* vals = Additional variable values to be set.
|
||||
* Returns:
|
||||
* Byte array with the rendered data to be output.
|
||||
* Standard Go error status.
|
||||
*/
|
||||
func (c *amContext) SubRender2(name string, vals map[string]any) ([]byte, error) {
|
||||
view, err := views.GetTemplate(name)
|
||||
if err != nil {
|
||||
@@ -328,15 +336,12 @@ func (c *amContext) SubRender2(name string, vals map[string]any) ([]byte, error)
|
||||
return nil, err
|
||||
}
|
||||
newmap := make(jet.VarMap)
|
||||
for k, v := range c.VarMap() {
|
||||
newmap.Set(k, v)
|
||||
}
|
||||
maps.Copy(newmap, c.VarMap())
|
||||
for k, v := range vals {
|
||||
newmap.Set(k, v)
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
err = view.Execute(buf, newmap, c)
|
||||
if err != nil {
|
||||
if err = view.Execute(buf, newmap, c); err != nil {
|
||||
log.Errorf("template \"%s\" failed subrender exec: %v", name, err)
|
||||
}
|
||||
return buf.Bytes(), err
|
||||
|
||||
Reference in New Issue
Block a user