bug fixes in Scan() results and conference list template

This commit is contained in:
2025-12-28 23:40:50 -07:00
parent 99dd8e78b9
commit 98a74487c2
8 changed files with 78 additions and 27 deletions
+17 -5
View File
@@ -17,6 +17,7 @@ import (
"sync" "sync"
"git.erbosoft.com/amy/amsterdam/util" "git.erbosoft.com/amy/amsterdam/util"
log "github.com/sirupsen/logrus"
) )
// Category is the structure defining a category. // Category is the structure defining a category.
@@ -71,7 +72,10 @@ func loadCategories(ctx context.Context) error {
return errors.New("internal error loading categories") return errors.New("internal error loading categories")
} }
var ncats int32 var ncats int32
rs.Scan(&ncats) err = rs.Scan(&ncats)
if err != nil {
return err
}
allCategories = make([]Category, 0, ncats) allCategories = make([]Category, 0, ncats)
err = amdb.SelectContext(ctx, &allCategories, "SELECT * FROM refcategory ORDER BY parent, name") err = amdb.SelectContext(ctx, &allCategories, "SELECT * FROM refcategory ORDER BY parent, name")
if err != nil { if err != nil {
@@ -243,7 +247,10 @@ func AmSearchCategories(ctx context.Context, oper int, term string, offset int,
return nil, -1, errors.New("internal error getting category total") return nil, -1, errors.New("internal error getting category total")
} }
var total int var total int
rs.Scan(&total) err = rs.Scan(&total)
if err != nil {
return nil, total, err
}
if total == 0 { if total == 0 {
return make([]*Category, 0), 0, nil return make([]*Category, 0), 0, nil
} }
@@ -258,10 +265,15 @@ func AmSearchCategories(ctx context.Context, oper int, term string, offset int,
rc := make([]*Category, 0, min(max, 1000)) rc := make([]*Category, 0, min(max, 1000))
for rs.Next() { for rs.Next() {
var catid int32 var catid int32
rs.Scan(&catid) err = rs.Scan(&catid)
c, err := AmGetCategory(ctx, catid)
if err == nil { if err == nil {
rc = append(rc, c) c, err := AmGetCategory(ctx, catid)
if err == nil {
rc = append(rc, c)
}
}
if err != nil {
log.Errorf("AmSearchCategoris scan error: %v", err)
} }
} }
return rc, total, nil return rc, total, nil
+22 -8
View File
@@ -23,6 +23,7 @@ import (
"git.erbosoft.com/amy/amsterdam/util" "git.erbosoft.com/amy/amsterdam/util"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
log "github.com/sirupsen/logrus"
"golang.org/x/text/language" "golang.org/x/text/language"
) )
@@ -219,11 +220,15 @@ func (c *Community) Membership(ctx context.Context, u *User) (bool, bool, uint16
if rs.Next() { if rs.Next() {
var locked bool var locked bool
var level uint16 var level uint16
rs.Scan(&locked, &level) err = rs.Scan(&locked, &level)
memberCache.Add(key, &memberCacheData{isMember: true, locked: locked, level: level}) if err == nil {
return true, locked, level, nil memberCache.Add(key, &memberCacheData{isMember: true, locked: locked, level: level})
return true, locked, level, nil
}
}
if err == nil {
memberCache.Add(key, &memberCacheData{isMember: false, locked: false, level: uint16(0)})
} }
memberCache.Add(key, &memberCacheData{isMember: false, locked: false, level: uint16(0)})
} }
return false, false, uint16(0), err return false, false, uint16(0), err
} }
@@ -379,7 +384,10 @@ func (c *Community) SetMembership(ctx context.Context, u *User, level uint16, lo
if rs.Next() { if rs.Next() {
var oldLevel uint16 var oldLevel uint16
var lockStatus bool var lockStatus bool
rs.Scan(&oldLevel, &lockStatus) err = rs.Scan(&oldLevel, &lockStatus)
if err != nil {
return err
}
if level != oldLevel || lockStatus != locked { if level != oldLevel || lockStatus != locked {
_, err := tx.ExecContext(ctx, "UPDATE commmember SET granted_lvl = ?, locked = ? WHERE commid = ? AND uid = ?", _, err := tx.ExecContext(ctx, "UPDATE commmember SET granted_lvl = ?, locked = ? WHERE commid = ? AND uid = ?",
level, locked, c.Id, u.Uid) level, locked, c.Id, u.Uid)
@@ -510,9 +518,12 @@ func (c *Community) SetProfileData(ctx context.Context, name string, alias strin
c.DeleteLevel = delete_lvl c.DeleteLevel = delete_lvl
c.JoinLevel = join_lvl c.JoinLevel = join_lvl
rs, err2 := amdb.QueryContext(ctx, "SELECT lastupdate FROM communities WHERE commid = ?", c.Id) rs, err2 := amdb.QueryContext(ctx, "SELECT lastupdate FROM communities WHERE commid = ?", c.Id)
if err2 != nil { if err2 == nil {
rs.Next() rs.Next()
rs.Scan(&c.LastUpdate) err2 = rs.Scan(&c.LastUpdate)
}
if err2 != nil {
log.Errorf("SetProfileData scan error: %v", err2)
} }
} }
return err return err
@@ -782,7 +793,10 @@ func AmAutoJoinCommunities(ctx context.Context, tx *sqlx.Tx, user *User) error {
for rows.Next() { for rows.Next() {
var cid int32 var cid int32
var lock bool var lock bool
rows.Scan(&cid, &lock) err = rows.Scan(&cid, &lock)
if err != nil {
break
}
if !slices.Contains(current, cid) { if !slices.Contains(current, cid) {
_, err = tx.ExecContext(ctx, "INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)", _, err = tx.ExecContext(ctx, "INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)",
cid, user.Uid, grantLevel, lock) cid, user.Uid, grantLevel, lock)
+4 -1
View File
@@ -122,7 +122,10 @@ func AmGetGlobalProperty(ctx context.Context, index int32) (string, error) {
return "", err return "", err
} }
if rs.Next() { if rs.Next() {
rs.Scan(&rc) err = rs.Scan(&rc)
if err != nil {
return "", err
}
globalProps[index] = rc globalProps[index] = rc
return rc, nil return rc, nil
} }
+4 -1
View File
@@ -93,7 +93,10 @@ func AmStoreImage(ctx context.Context, typecode int16, owner int32, mimetype str
var img *ImageStore var img *ImageStore
if rs.Next() { if rs.Next() {
var id int32 var id int32
rs.Scan(&id) err = rs.Scan(&id)
if err != nil {
return nil, err
}
img, err = AmLoadImage(ctx, id) img, err = AmLoadImage(ctx, id)
if err != nil { if err != nil {
return nil, err return nil, err
+4 -1
View File
@@ -73,7 +73,10 @@ func AmTestIPBan(ctx context.Context, ip_address string) (string, error) {
} }
defer rows.Close() defer rows.Close()
if rows.Next() { if rows.Next() {
rows.Scan(&rc) err = rows.Scan(&rc)
if err != nil {
return "", err
}
knownBans[ip_address] = rc knownBans[ip_address] = rc
return rc, nil return rc, nil
} }
+12 -5
View File
@@ -17,6 +17,7 @@ import (
"time" "time"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
log "github.com/sirupsen/logrus"
) )
// Topic is the top-level structure detailing topics. // Topic is the top-level structure detailing topics.
@@ -61,9 +62,9 @@ func (t *Topic) GetLastRead(ctx context.Context, u *User) (int32, error) {
} }
var rc int32 = -1 var rc int32 = -1
if rs.Next() { if rs.Next() {
rs.Scan(&rc) err = rs.Scan(&rc)
} }
return rc, nil return rc, err
} }
// SetLastRead sets the "last read" message for a user on a topic. // SetLastRead sets the "last read" message for a user on a topic.
@@ -103,6 +104,8 @@ type TopicSummary struct {
Archived bool // is topic archived? Archived bool // is topic archived?
Subscribed bool // is topic subscribed? Subscribed bool // is topic subscribed?
Hidden bool // is topic hidden? Hidden bool // is topic hidden?
Sticky bool // is topic sticky?
NewFlag bool // does topic have new messages?
} }
/* AmGetTopic retrieves a topic by ID. /* AmGetTopic retrieves a topic by ID.
@@ -310,9 +313,13 @@ func AmListTopics(ctx context.Context, confid int32, uid int32, viewOption int,
rc := make([]*TopicSummary, 0) rc := make([]*TopicSummary, 0)
for rs.Next() { for rs.Next() {
var rec TopicSummary var rec TopicSummary
rs.Scan(&rec.TopicID, &rec.Number, &rec.Name, &rec.Unread, &rec.Total, &rec.LastUpdate, &rec.Frozen, &rec.Archived, err = rs.Scan(&rec.TopicID, &rec.Number, &rec.Name, &rec.Unread, &rec.Total, &rec.LastUpdate, &rec.Frozen,
&rec.Subscribed, &rec.Hidden) &rec.Archived, &rec.Subscribed, &rec.Hidden, &rec.Sticky, &rec.NewFlag)
rc = append(rc, &rec) if err != nil {
log.Errorf("AmListTopics scan error: %v", err)
} else {
rc = append(rc, &rec)
}
} }
return rc, nil return rc, nil
} }
+13 -4
View File
@@ -925,7 +925,10 @@ func AmSearchUsers(ctx context.Context, field int, oper int, term string, offset
return nil, -1, errors.New("internal error getting count") return nil, -1, errors.New("internal error getting count")
} }
var total int var total int
rs.Scan(&total) err = rs.Scan(&total)
if err != nil {
return nil, -1, err
}
if total == 0 { if total == 0 {
return make([]*User, 0), 0, nil return make([]*User, 0), 0, nil
} }
@@ -942,10 +945,16 @@ func AmSearchUsers(ctx context.Context, field int, oper int, term string, offset
rc := make([]*User, 0, min(max, 10000)) rc := make([]*User, 0, min(max, 10000))
for rs.Next() { for rs.Next() {
var uid int32 var uid int32
rs.Scan(&uid) err = rs.Scan(&uid)
u, err := AmGetUser(ctx, uid)
if err == nil { if err == nil {
rc = append(rc, u) var u *User
u, err = AmGetUser(ctx, uid)
if err == nil {
rc = append(rc, u)
}
}
if err != nil {
log.Errorf("AmSearchUsers scan error: %v", err)
} }
} }
return rc, total, nil return rc, total, nil
+2 -2
View File
@@ -23,12 +23,12 @@
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span> <span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
<div class="flex-1"> <div class="flex-1">
<div class="mb-2"> <div class="mb-2">
<a href="/comm/{{ commAlias }}/conf/{{ c.AliasesQ()[0] }}" <a href="/comm/{{ commAlias }}/conf/{{ c.AliasesQ(.Ctx())[0] }}"
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a> class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span> <span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
</div> </div>
<div class="text-sm text-gray-700 mb-1"> <div class="text-sm text-gray-700 mb-1">
{{ hl := c.HostsQ() }} {{ hl := c.HostsQ(.Ctx()) }}
{{ if len(hl) == 1 }} {{ if len(hl) == 1 }}
<span class="font-medium">Host:</span> <span class="font-medium">Host:</span>
{{ else }} {{ else }}