From c958bc582627394ffbf588f86c1bdb77651cf7b1 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 30 Dec 2025 23:19:39 -0700 Subject: [PATCH] completed the Scan() error handling --- conference.go | 12 +++++ database/category.go | 21 +++------ database/community.go | 102 +++++++++++++++++++--------------------- database/conference.go | 45 +++++++++++------- database/contactinfo.go | 8 ++-- database/post.go | 29 +++++++++--- database/services.go | 22 ++++----- database/topic.go | 28 +++++++---- database/user.go | 42 ++++++----------- ui/amcontext.go | 23 +++++---- 10 files changed, 179 insertions(+), 153 deletions(-) diff --git a/conference.go b/conference.go index fdf6684..f933ed1 100644 --- a/conference.go +++ b/conference.go @@ -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 := "<>" 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") { diff --git a/database/category.go b/database/category.go index 18e0dac..af974e0 100644 --- a/database/category.go +++ b/database/category.go @@ -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) diff --git a/database/community.go b/database/community.go index e979a18..1bdf7ae 100644 --- a/database/community.go +++ b/database/community.go @@ -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,10 +338,11 @@ 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) - u, err := AmGetUser(ctx, uid) - if err == nil { - rc = append(rc, u) + 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,8 +551,9 @@ func (c *Community) Touch(ctx context.Context) error { if err == nil { rs.Next() var na time.Time - rs.Scan(&na) - c.LastAccess = &na + if err = rs.Scan(&na); err == nil { + c.LastAccess = &na + } } } return err @@ -573,9 +569,10 @@ 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) - c.LastAccess = &na - c.LastUpdate = &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) - return AmGetCommunity(ctx, 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) - return AmGetCommunityTx(ctx, tx, 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,10 +1022,11 @@ 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) - c, err := AmGetCommunity(ctx, commid) - if err == nil { - rc = append(rc, c) + 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,10 +1105,11 @@ 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) - c, err := AmGetCommunity(ctx, commid) - if err == nil { - rc = append(rc, c) + if err = rs.Scan(&commid); err == nil { + c, err := AmGetCommunity(ctx, commid) + if err == nil { + rc = append(rc, c) + } } } return rc, total, nil diff --git a/database/conference.go b/database/conference.go index 1ae31a5..c8dfbdb 100644 --- a/database/conference.go +++ b/database/conference.go @@ -101,10 +101,11 @@ func (c *Conference) Hosts(ctx context.Context) ([]*User, error) { rc := make([]*User, 0, 5) for rs.Next() { var uid int32 - rs.Scan(&uid) - u, err := AmGetUser(ctx, uid) - if err == nil { - rc = append(rc, u) + 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) - conf, err := AmGetConference(ctx, confid) - if err == nil { - rc = append(rc, conf) + 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 diff --git a/database/contactinfo.go b/database/contactinfo.go index 05f36ec..854fd75 100644 --- a/database/contactinfo.go +++ b/database/contactinfo.go @@ -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. diff --git a/database/post.go b/database/post.go index d6310b0..fff6d64 100644 --- a/database/post.go +++ b/database/post.go @@ -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)) diff --git a/database/services.go b/database/services.go index a6bd44d..7341a5c 100644 --- a/database/services.go +++ b/database/services.go @@ -144,8 +144,9 @@ 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) - a = append(a, dom.byIndex[ndx]) + if err = rs.Scan(&ndx); err == nil { + a = append(a, dom.byIndex[ndx]) + } } servicesCache.Add(cid, a) rc = a @@ -175,8 +176,9 @@ 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) - a = append(a, dom.byIndex[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 } } diff --git a/database/topic.go b/database/topic.go index 95261a7..f8b294f 100644 --- a/database/topic.go +++ b/database/topic.go @@ -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 diff --git a/database/user.go b/database/user.go index 0e37109..da47d7a 100644 --- a/database/user.go +++ b/database/user.go @@ -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 { diff --git a/ui/amcontext.go b/ui/amcontext.go index 12f9b87..31a2447 100644 --- a/ui/amcontext.go +++ b/ui/amcontext.go @@ -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