factoring out a lot of string constant values

This commit is contained in:
2026-05-03 22:39:11 -06:00
parent 64161721bf
commit 08a10a55dd
12 changed files with 150 additions and 103 deletions
+24 -24
View File
@@ -254,10 +254,10 @@ func (p *PostHeader) Text(ctx context.Context) (string, error) {
// Link returns a link string to this post.
func (p *PostHeader) Link(ctx context.Context, commid int32, scope string) (string, error) {
if scope == "topic" {
if scope == PLSCOPE_TOPIC {
return fmt.Sprintf("%d", p.Num), nil
}
if scope == "conference" || scope == "community" || scope == "global" {
if scope == PLSCOPE_CONFERENCE || scope == PLSCOPE_COMMUNITY || scope == PLSCOPE_GLOBAL {
topic, err := AmGetTopic(ctx, p.TopicId)
if err != nil {
return "", err
@@ -720,55 +720,55 @@ func decodeSearchScope(ctx context.Context, scopeValues []any) (string, *Communi
}
if thisComm, ok := scopeValues[i].(*Community); ok {
if myComm != nil {
return "error", nil, nil, nil, errors.New("cannot specify multiple communities")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("cannot specify multiple communities")
}
myComm = thisComm
continue
}
if thisConf, ok := scopeValues[i].(*Conference); ok {
if myConf != nil {
return "error", nil, nil, nil, errors.New("cannot specify multiple conferences")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("cannot specify multiple conferences")
}
myConf = thisConf
continue
}
if thisTopic, ok := scopeValues[i].(*Topic); ok {
if myTopic != nil {
return "error", nil, nil, nil, errors.New("cannot specify multiple topics")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("cannot specify multiple topics")
}
myTopic = thisTopic
continue
}
return "error", nil, nil, nil, errors.New("invalid item specified in scope")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("invalid item specified in scope")
}
// Based on which slots are full, determine the scope. Also error-check relations between the specified slots.
if myComm == nil {
if myConf != nil || myTopic != nil {
return "error", nil, nil, nil, errors.New("conference/topic specified without community")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("conference/topic specified without community")
}
return "global", nil, nil, nil, nil
return PLSCOPE_GLOBAL, nil, nil, nil, nil
}
if myConf == nil {
if myTopic != nil {
return "error", nil, nil, nil, errors.New("topic specified without conference")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("topic specified without conference")
}
return "community", myComm, nil, nil, nil
return PLSCOPE_COMMUNITY, myComm, nil, nil, nil
}
f, err := myConf.InCommunity(ctx, myComm)
if err != nil {
return "error", nil, nil, nil, err
return PLSCOPE_ERROR, nil, nil, nil, err
}
if !f {
return "error", nil, nil, nil, errors.New("community does not contain conference")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("community does not contain conference")
}
if myTopic == nil {
return "conference", myComm, myConf, nil, nil
return PLSCOPE_CONFERENCE, myComm, myConf, nil, nil
}
if myTopic.ConfId != myConf.ConfId {
return "error", nil, nil, nil, errors.New("conference does not contain topic")
return PLSCOPE_ERROR, nil, nil, nil, errors.New("conference does not contain topic")
}
return "topic", myComm, myConf, myTopic, nil
return PLSCOPE_TOPIC, myComm, myConf, myTopic, nil
}
/* AmSearchPosts finds posts by using full text search on their contents.
@@ -794,7 +794,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
}
// Get the proper service index to match against the community services.
confService, err := AmGetServiceIndex("community", "Conference")
confService, err := AmGetServiceIndex(AM_DOMAIN_COMMUNITY, AM_SVC_CONFERENCE)
if err != nil {
return nil, -1, err
}
@@ -802,7 +802,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
// Get the count of matching posts.
var count int
switch scope {
case "global":
case PLSCOPE_GLOBAL:
err = amdb.GetContext(ctx, &count, `SELECT COUNT(*)
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -810,7 +810,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
LEFT JOIN confmember x ON (c.confid = x.confid AND u.uid = x.uid)
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?)`, u.Uid, confService, searchTerms)
case "community":
case PLSCOPE_COMMUNITY:
err = amdb.GetContext(ctx, &count, `SELECT COUNT(*)
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -818,7 +818,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
LEFT JOIN confmember x ON (c.confid = x.confid AND u.uid = x.uid)
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND q.commid = ? AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?)`, u.Uid, confService, comm.Id, searchTerms)
case "conference":
case PLSCOPE_CONFERENCE:
err = amdb.GetContext(ctx, &count, `SELECT COUNT(*)
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -826,7 +826,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
LEFT JOIN confmember x ON (c.confid = x.confid AND u.uid = x.uid)
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND q.commid = ? AND c.confid = ? AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?)`, u.Uid, confService, comm.Id, conf.ConfId, searchTerms)
case "topic":
case PLSCOPE_TOPIC:
err = amdb.GetContext(ctx, &count, `SELECT COUNT(*)
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -844,7 +844,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
// Get the matching posts themselves.
var rs *sql.Rows
switch scope {
case "global":
case PLSCOPE_GLOBAL:
rs, err = amdb.QueryContext(ctx, `SELECT q.commid, q.alias, c.confid, t.topicid, t.num, p.postid, p.num, u2.username, p.posted, p.linecount, d.data
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -853,7 +853,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?) ORDER BY q.commname, c.name, t.num, p.num
LIMIT ? OFFSET ?`, u.Uid, confService, searchTerms, max, offset)
case "community":
case PLSCOPE_COMMUNITY:
rs, err = amdb.QueryContext(ctx, `SELECT q.commid, q.alias, c.confid, t.topicid, t.num, p.postid, p.num, u2.username, p.posted, p.linecount, d.data
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -862,7 +862,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND q.commid = ? AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?) ORDER BY q.commname, c.name, t.num, p.num
LIMIT ? OFFSET ?`, u.Uid, confService, comm.Id, searchTerms, max, offset)
case "conference":
case PLSCOPE_CONFERENCE:
rs, err = amdb.QueryContext(ctx, `SELECT q.commid, q.alias, c.confid, t.topicid, t.num, p.postid, p.num, u2.username, p.posted, p.linecount, d.data
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
@@ -871,7 +871,7 @@ func AmSearchPosts(ctx context.Context, searchTerms string, u *User, offset, max
WHERE u.uid = ? AND f.ftr_code = ? AND GREATEST(u.base_lvl,m.granted_lvl,s.granted_lvl,COALESCE(x.granted_lvl,0)) >= c.read_lvl
AND q.commid = ? AND c.confid = ? AND p.scribble_uid IS NULL AND MATCH(d.data) AGAINST (?) ORDER BY q.commname, c.name, t.num, p.num
LIMIT ? OFFSET ?`, u.Uid, confService, comm.Id, conf.ConfId, searchTerms, max, offset)
case "topic":
case PLSCOPE_TOPIC:
rs, err = amdb.QueryContext(ctx, `SELECT q.commid, q.alias, c.confid, t.topicid, t.num, p.postid, p.num, u2.username, p.posted, p.linecount, d.data
FROM communities q JOIN commtoconf s ON s.commid = q.commid JOIN confs c ON c.confid = s.confid
JOIN commmember m ON m.commid = q.commid JOIN users u ON u.uid = m.uid JOIN commftrs f ON f.commid = q.commid
+63 -43
View File
@@ -20,6 +20,25 @@ import (
"strings"
)
// Post link scopes.
const (
PLSCOPE_GLOBAL = "global"
PLSCOPE_COMMUNITY = "community"
PLSCOPE_CONFERENCE = "conference"
PLSCOPE_TOPIC = "topic"
PLSCOPE_ERROR = "error"
)
// Post link classifications.
const (
PLCLASS_COMMUNITY = "community"
PLCLASS_CONFERENCE = "conference"
PLCLASS_TOPIC = "topic"
PLCLASS_POST = "post"
PLCLASS_POSTRANGE = "postrange"
PLCLASS_POSTOPENRANGE = "postopenrange"
)
// PostLinkData is the structure holding the decoded parts of the post link.
type PostLinkData struct {
Community string
@@ -121,53 +140,53 @@ func (d *PostLinkData) Classify() (string, string) {
if d.FirstPost == -1 {
return "", ""
} else if d.LastPost == -1 {
return "topic", "postopenrange"
return PLSCOPE_TOPIC, PLCLASS_POSTOPENRANGE
} else if d.LastPost == d.FirstPost {
return "topic", "post"
return PLSCOPE_TOPIC, PLCLASS_POST
} else {
return "topic", "postrange"
return PLSCOPE_TOPIC, PLCLASS_POSTRANGE
}
} else {
if d.FirstPost == -1 {
return "conference", "topic"
return PLSCOPE_CONFERENCE, PLCLASS_TOPIC
} else if d.LastPost == -1 {
return "conference", "postopenrange"
return PLSCOPE_CONFERENCE, PLCLASS_POSTOPENRANGE
} else if d.LastPost == d.FirstPost {
return "conference", "post"
return PLSCOPE_CONFERENCE, PLCLASS_POST
} else {
return "conference", "postrange"
return PLSCOPE_CONFERENCE, PLCLASS_POSTRANGE
}
}
} else {
if d.Topic == -1 {
return "community", "conference"
return PLSCOPE_COMMUNITY, PLCLASS_CONFERENCE
} else {
if d.FirstPost == -1 {
return "community", "topic"
return PLSCOPE_COMMUNITY, PLCLASS_TOPIC
} else if d.LastPost == -1 {
return "community", "postopenrange"
return PLSCOPE_COMMUNITY, PLCLASS_POSTOPENRANGE
} else if d.LastPost == d.FirstPost {
return "community", "post"
return PLSCOPE_COMMUNITY, PLCLASS_POST
} else {
return "community", "postrange"
return PLSCOPE_COMMUNITY, PLCLASS_POSTRANGE
}
}
}
} else {
if d.Conference == "" {
return "global", "community"
return PLSCOPE_GLOBAL, PLCLASS_COMMUNITY
} else {
if d.Topic == -1 {
return "global", "conference"
return PLSCOPE_GLOBAL, PLCLASS_CONFERENCE
} else {
if d.FirstPost == -1 {
return "global", "topic"
return PLSCOPE_GLOBAL, PLCLASS_TOPIC
} else if d.LastPost == -1 {
return "global", "postopenrange"
return PLSCOPE_GLOBAL, PLCLASS_POSTOPENRANGE
} else if d.LastPost == d.FirstPost {
return "global", "post"
return PLSCOPE_GLOBAL, PLCLASS_POST
} else {
return "global", "postrange"
return PLSCOPE_GLOBAL, PLCLASS_POSTRANGE
}
}
}
@@ -276,25 +295,25 @@ func AmDecodePostLink(data string) (*PostLinkData, error) {
if len(data) > maxLinkLength {
return nil, errors.New("post link string too long")
}
rc := PostLinkData{
rc := new(PostLinkData{
Community: "",
Conference: "",
Topic: -1,
FirstPost: -1,
LastPost: -1,
}
})
work := data
// First test: Bang
pos := strings.IndexByte(work, '!')
if pos > 0 {
err := validateCommunity(work[:pos], &rc)
err := validateCommunity(work[:pos], rc)
if err != nil {
return nil, err
}
work = work[pos+1:]
if len(work) == 0 {
return &rc, nil // community link
return rc, nil // community link
}
} else if pos == 0 {
return nil, errors.New("cannot have ! at beginning")
@@ -306,14 +325,14 @@ func AmDecodePostLink(data string) (*PostLinkData, error) {
// no dots in here, must be either "postlink" or "community!conference"
var err error
if rc.Community == "" {
err = decodePostRange(work, &rc)
err = decodePostRange(work, rc)
} else {
err = validateConference(work, &rc)
err = validateConference(work, rc)
}
if err != nil {
return nil, err
}
return &rc, nil
return rc, nil
}
// Peel off the initial substring before the dot.
@@ -324,19 +343,19 @@ func AmDecodePostLink(data string) (*PostLinkData, error) {
var err error
if rc.Community == "" {
// it's either "conference." or "topic." - try the latter first
err = decodeTopicNumber(confOrTopic, &rc)
err = decodeTopicNumber(confOrTopic, rc)
if err != nil {
// it's not a topic number, try it as a conference name
err = validateConference(confOrTopic, &rc)
err = validateConference(confOrTopic, rc)
}
} else {
// it was "community!conference."
err = validateConference(confOrTopic, &rc)
err = validateConference(confOrTopic, rc)
}
if err != nil {
return nil, err
}
return &rc, nil
return rc, nil
}
// Third test: Dot #2
@@ -347,38 +366,38 @@ func AmDecodePostLink(data string) (*PostLinkData, error) {
if rc.Community == "" {
// either "conference.topic" or "topic.posts"
isTopic := false
err = decodeTopicNumber(confOrTopic, &rc)
err = decodeTopicNumber(confOrTopic, rc)
if err != nil {
// it's "conference.topic"
err = validateConference(confOrTopic, &rc)
err = validateConference(confOrTopic, rc)
isTopic = true
}
if err == nil {
if isTopic {
err = decodeTopicNumber(work, &rc)
err = decodeTopicNumber(work, rc)
} else {
err = decodePostRange(work, &rc)
err = decodePostRange(work, rc)
}
}
} else {
// we have "community!conference.topic"
err = validateConference(confOrTopic, &rc)
err = validateConference(confOrTopic, rc)
if err == nil {
err = decodeTopicNumber(work, &rc)
err = decodeTopicNumber(work, rc)
}
}
if err != nil {
return nil, err
}
return &rc, nil
return rc, nil
} else if pos == 0 {
return nil, errors.New("cannot have . at beginning of string")
}
// We definitely have "conference.topic.something" or "community!conference.topic.something"
err := validateConference(confOrTopic, &rc)
err := validateConference(confOrTopic, rc)
if err == nil {
err = decodeTopicNumber(work[:pos], &rc)
err = decodeTopicNumber(work[:pos], rc)
}
if err != nil {
return nil, err
@@ -386,22 +405,23 @@ func AmDecodePostLink(data string) (*PostLinkData, error) {
work = work[pos+1:]
if len(work) == 0 {
// we had "conference.topic." or "communtiy!conference.topic.", those are both valid
return &rc, nil
return rc, nil
}
err = decodePostRange(work, &rc) // the rest must be the post range
err = decodePostRange(work, rc) // the rest must be the post range
if err != nil {
return nil, err
}
return &rc, nil
return rc, nil
}
// AmCreatePostLinkContext creates a new empty post link context.
func AmCreatePostLinkContext(community string, commid int32, conference string, topic int16) *PostLinkData {
return &PostLinkData{
return new(PostLinkData{
Community: community,
CommId: commid,
Conference: conference,
Topic: topic,
FirstPost: -1,
LastPost: -1,
}
})
}
+23 -9
View File
@@ -25,6 +25,20 @@ import (
"gopkg.in/yaml.v3"
)
// The service domain names.
const (
AM_DOMAIN_COMMUNITY = "community"
)
// The service names.
const (
AM_SVC_PROFILE = "Profile"
AM_SVC_ADMIN = "Admin"
AM_SVC_SYSADMIN = "SysAdmin"
AM_SVC_CONFERENCE = "Conference"
AM_SVC_MEMBERS = "Members"
)
// ServiceVTable is a series of functions called for services on specific events.
type ServiceVTable interface {
OnNewCommunity(context.Context, *sqlx.Tx, *Community) error
@@ -114,13 +128,13 @@ func init() {
serviceRoot.Domains[i].seqOrder = sqo
serviceRoot.byName[dom.DomainName] = &(serviceRoot.Domains[i])
}
dom := serviceRoot.byName["community"]
dom := serviceRoot.byName[AM_DOMAIN_COMMUNITY]
empty := emptyServiceVTable{}
dom.byId["Profile"].vtable = &empty
dom.byId["Admin"].vtable = &empty
dom.byId["SysAdmin"].vtable = &empty
dom.byId["Conference"].vtable = &(conferenceServiceVTable{})
dom.byId["Members"].vtable = &empty
dom.byId[AM_SVC_PROFILE].vtable = &empty
dom.byId[AM_SVC_ADMIN].vtable = &empty
dom.byId[AM_SVC_SYSADMIN].vtable = &empty
dom.byId[AM_SVC_CONFERENCE].vtable = &(conferenceServiceVTable{})
dom.byId[AM_SVC_MEMBERS].vtable = &empty
}
// setupServicesCache sets up the services cache.
@@ -166,7 +180,7 @@ func AmGetCommunityServices(ctx context.Context, cid int32) ([]*ServiceDef, erro
if err != nil {
return nil, err
}
dom := serviceRoot.byName["community"]
dom := serviceRoot.byName[AM_DOMAIN_COMMUNITY]
a := make([]*ServiceDef, 0, len(dom.Services))
for rs.Next() {
var ndx int16
@@ -198,7 +212,7 @@ func AmGetCommunityServicesTx(ctx context.Context, tx *sqlx.Tx, cid int32) ([]*S
if err != nil {
return nil, err
}
dom := serviceRoot.byName["community"]
dom := serviceRoot.byName[AM_DOMAIN_COMMUNITY]
a := make([]*ServiceDef, 0, len(dom.Services))
for rs.Next() {
var ndx int16
@@ -222,7 +236,7 @@ func AmGetCommunityServicesTx(ctx context.Context, tx *sqlx.Tx, cid int32) ([]*S
* Standard Go error status.
*/
func AmEstablishCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Community) error {
dom := serviceRoot.byName["community"]
dom := serviceRoot.byName[AM_DOMAIN_COMMUNITY]
a := make([]*ServiceDef, 0, len(dom.Services))
for i, svc := range dom.Services {
if svc.Default {
+2 -2
View File
@@ -44,10 +44,10 @@ type Topic struct {
// Link returns a link string to this topic.
func (t *Topic) Link(ctx context.Context, commid int32, scope string) (string, error) {
if scope == "conference" {
if scope == PLSCOPE_CONFERENCE {
return fmt.Sprintf("%d.", t.Number), nil
}
if scope == "community" || scope == "global" {
if scope == PLSCOPE_COMMUNITY || scope == PLSCOPE_GLOBAL {
conf, err := AmGetConference(ctx, t.ConfId)
if err == nil {
var plink string