diff --git a/database/community.go b/database/community.go index c9698b0..60eee10 100644 --- a/database/community.go +++ b/database/community.go @@ -605,16 +605,11 @@ func AmGetCommunity(ctx context.Context, id int32) (*Community, error) { defer getCommunityMutex.Unlock() rc, ok := communityCache.Get(id) if !ok { - var dbdata []Community - if err := amdb.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id); err != nil { + var newcomm Community + if err := amdb.GetContext(ctx, &newcomm, "SELECT * from communities WHERE commid = ?", id); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("community with ID %d not found", id) - } else if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetCommunity(%d): too many responses(%d)", id, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &newcomm communityCache.Add(id, rc) } return rc.(*Community), nil @@ -634,16 +629,11 @@ func AmGetCommunityTx(ctx context.Context, tx *sqlx.Tx, id int32) (*Community, e defer getCommunityMutex.Unlock() rc, ok := communityCache.Get(id) if !ok { - var dbdata []Community - if err := tx.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id); err != nil { + var newcomm Community + if err := tx.GetContext(ctx, &newcomm, "SELECT * from communities WHERE commid = ?", id); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("community with ID %d not found", id) - } else if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetCommunity(%d): too many responses(%d)", id, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &newcomm communityCache.Add(id, rc) } return rc.(*Community), nil @@ -809,17 +799,11 @@ func internalGetCommProp(ctx context.Context, cid int32, ndx int32) (*CommunityP defer getCommunityPropMutex.Unlock() rc, ok := communityPropCache.Get(key) if !ok { - var dbdata []CommunityProperties - if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx); err != nil { + var prop CommunityProperties + if err = amdb.GetContext(ctx, &prop, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, nil - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetCommunityProperty(%d): too many responses(%d)", cid, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &prop communityPropCache.Add(key, rc) } return rc.(*CommunityProperties), nil diff --git a/database/conference.go b/database/conference.go index e947eba..a3e9c22 100644 --- a/database/conference.go +++ b/database/conference.go @@ -415,11 +415,13 @@ func (c *Conference) SaveFlags(ctx context.Context, f *util.OptionSet) error { // Settings returns the settings for a user. func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings, error) { - var dbdata []ConferenceSettings - 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 { + var settings ConferenceSettings + err := amdb.GetContext(ctx, &settings, "SELECT * FROM confsettings WHERE confid = ? AND uid = ?", c.ConfId, u.Uid) + switch err { + case nil: + settings.newflag = false + return &settings, nil + case sql.ErrNoRows: settings := ConferenceSettings{ ConfId: c.ConfId, Uid: u.Uid, @@ -430,11 +432,7 @@ func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings } return &settings, nil } - if len(dbdata) > 1 { - return nil, fmt.Errorf("conference.Settings(c=%d,u=%d): too many results (%d)", c.ConfId, u.Uid, len(dbdata)) - } - dbdata[0].newflag = false - return &(dbdata[0]), nil + return nil, err } // Link returns a link string to this conference. @@ -465,36 +463,32 @@ func (c *Conference) SetInfo(ctx context.Context, name, descr string, read_lvl, hide_lvl = ?, nuke_lvl = ?, change_lvl = ?, delete_lvl = ?, lastupdate = NOW() WHERE confid = ?`, name, descr, read_lvl, post_lvl, create_lvl, hide_lvl, nuke_lvl, change_lvl, delete_lvl, c.ConfId) if err == nil { - var tmp []Conference - err := amdb.SelectContext(ctx, &tmp, "SELECT * FROM confs WHERE confid = ?", c.ConfId) + var tmp Conference + err := amdb.GetContext(ctx, &tmp, "SELECT * FROM confs WHERE confid = ?", c.ConfId) if err == nil { - if len(tmp) != 1 { - err = errors.New("internal error rereading conference") - } else { - if c.Name != tmp[0].Name { - AmStoreAudit(AmNewCommAudit(AuditConferenceName, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", c.ConfId), fmt.Sprintf("name='%s'", tmp[0].Name))) - } - deltaSecurity := false - if (c.ReadLevel != tmp[0].ReadLevel) || (c.PostLevel != tmp[0].PostLevel) || (c.CreateLevel != tmp[0].CreateLevel) || (c.HideLevel != tmp[0].HideLevel) { - deltaSecurity = true - } - if (c.NukeLevel != tmp[0].NukeLevel) || (c.ChangeLevel != tmp[0].ChangeLevel) || (c.DeleteLevel != tmp[0].DeleteLevel) { - deltaSecurity = true - } - if deltaSecurity { - AmStoreAudit(AmNewCommAudit(AuditConferenceSecurity, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", c.ConfId))) - } - c.Name = tmp[0].Name - c.Description = tmp[0].Description - c.ReadLevel = tmp[0].ReadLevel - c.PostLevel = tmp[0].PostLevel - c.CreateLevel = tmp[0].CreateLevel - c.HideLevel = tmp[0].HideLevel - c.NukeLevel = tmp[0].NukeLevel - c.ChangeLevel = tmp[0].ChangeLevel - c.DeleteLevel = tmp[0].DeleteLevel - c.LastUpdate = tmp[0].LastUpdate + if c.Name != tmp.Name { + AmStoreAudit(AmNewCommAudit(AuditConferenceName, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", c.ConfId), fmt.Sprintf("name='%s'", tmp.Name))) } + deltaSecurity := false + if (c.ReadLevel != tmp.ReadLevel) || (c.PostLevel != tmp.PostLevel) || (c.CreateLevel != tmp.CreateLevel) || (c.HideLevel != tmp.HideLevel) { + deltaSecurity = true + } + if (c.NukeLevel != tmp.NukeLevel) || (c.ChangeLevel != tmp.ChangeLevel) || (c.DeleteLevel != tmp.DeleteLevel) { + deltaSecurity = true + } + if deltaSecurity { + AmStoreAudit(AmNewCommAudit(AuditConferenceSecurity, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", c.ConfId))) + } + c.Name = tmp.Name + c.Description = tmp.Description + c.ReadLevel = tmp.ReadLevel + c.PostLevel = tmp.PostLevel + c.CreateLevel = tmp.CreateLevel + c.HideLevel = tmp.HideLevel + c.NukeLevel = tmp.NukeLevel + c.ChangeLevel = tmp.ChangeLevel + c.DeleteLevel = tmp.DeleteLevel + c.LastUpdate = tmp.LastUpdate } } return err @@ -1022,16 +1016,11 @@ func AmGetConference(ctx context.Context, id int32) (*Conference, error) { defer getConferenceMutex.Unlock() rc, ok := conferenceCache.Get(id) if !ok { - var dbdata []Conference - if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from confs where confid = ?", id); err != nil { + var conf Conference + if err = amdb.GetContext(ctx, &conf, "SELECT * from confs where confid = ?"); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("conference with ID %d not found", id) - } else if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetConference(%d): too many responses(%d)", id, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &conf conferenceCache.Add(id, rc) } return rc.(*Conference), err @@ -1157,17 +1146,11 @@ func internalGetConfProp(ctx context.Context, confid int32, ndx int32) (*Confere defer getConferencePropMutex.Unlock() rc, ok := conferencePropCache.Get(key) if !ok { - var dbdata []ConferenceProperties - if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propconf WHERE confid = ? AND ndx = ?", confid, ndx); err != nil { + var prop ConferenceProperties + if err = amdb.GetContext(ctx, &prop, "SELECT * from propconf WHERE confid = ? AND ndx = ?", confid, ndx); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, nil - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetConferenceProperty(%d): too many responses(%d)", confid, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &prop conferencePropCache.Add(key, rc) } return rc.(*ConferenceProperties), nil @@ -1304,16 +1287,14 @@ func AmCreateConference(ctx context.Context, comm *Community, name, alias, descr if err != nil { return nil, err } - var rc []Conference - err = tx.SelectContext(ctx, &rc, "SELECT * FROM confs WHERE confid = ?", int32(newId)) + var rc Conference + err = tx.GetContext(ctx, &rc, "SELECT * FROM confs WHERE confid = ?", int32(newId)) if err != nil { return nil, err - } else if len(rc) != 1 { - return nil, errors.New("internal error reading back conference") } // Attach the alias to the conference. - _, err = tx.ExecContext(ctx, "INSERT INTO confalias (confid, alias) VALUES (?, ?)", rc[0].ConfId, alias) + _, err = tx.ExecContext(ctx, "INSERT INTO confalias (confid, alias) VALUES (?, ?)", rc.ConfId, alias) if err != nil { return nil, err } @@ -1327,14 +1308,14 @@ func AmCreateConference(ctx context.Context, comm *Community, name, alias, descr } // Link the conference into the community, and set the hide flag. - _, err = tx.ExecContext(ctx, "INSERT INTO commtoconf (commid, confid, sequence, hide_list) VALUES (?, ?, ?, ?)", comm.Id, rc[0].ConfId, + _, err = tx.ExecContext(ctx, "INSERT INTO commtoconf (commid, confid, sequence, hide_list) VALUES (?, ?, ?, ?)", comm.Id, rc.ConfId, int16(seq+COMMTOCONF_SEQ_SPACING), hide_list) if err != nil { return nil, err } // Make the specified user the first host of the conference. - _, err = tx.ExecContext(ctx, "INSERT INTO confmember (confid, uid, granted_lvl) VALUES (?, ?, ?)", rc[0].ConfId, u.Uid, AmDefaultRole("Conference.NewHost").Level()) + _, err = tx.ExecContext(ctx, "INSERT INTO confmember (confid, uid, granted_lvl) VALUES (?, ?, ?)", rc.ConfId, u.Uid, AmDefaultRole("Conference.NewHost").Level()) if err != nil { return nil, err } @@ -1344,7 +1325,7 @@ func AmCreateConference(ctx context.Context, comm *Community, name, alias, descr } // Add the new conference to the cache, and create our audit record. - conferenceCache.Add(rc[0].ConfId, &(rc[0])) - AmStoreAudit(AmNewCommAudit(AuditConferenceCreate, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", rc[0].ConfId), fmt.Sprintf("name=%s", name), fmt.Sprintf("alias=%s", alias))) - return &(rc[0]), nil + conferenceCache.Add(rc.ConfId, &rc) + AmStoreAudit(AmNewCommAudit(AuditConferenceCreate, u.Uid, comm.Id, ipaddr, fmt.Sprintf("confid=%d", rc.ConfId), fmt.Sprintf("name=%s", name), fmt.Sprintf("alias=%s", alias))) + return &rc, nil } diff --git a/database/contactinfo.go b/database/contactinfo.go index f6da0d2..99ab872 100644 --- a/database/contactinfo.go +++ b/database/contactinfo.go @@ -250,16 +250,10 @@ func setupContactsCache() { // internalContactInfo retrieves the contact info from the database. func internalContactInfo(ctx context.Context, id int32) (*ContactInfo, error) { - var dbdata []ContactInfo - err := amdb.SelectContext(ctx, &dbdata, "SELECT * from contacts WHERE contactid = ?", id) + var cinf ContactInfo + err := amdb.GetContext(ctx, &cinf, "SELECT * from contacts WHERE contactid = ?", id) if err == nil { - if len(dbdata) > 1 { - err = fmt.Errorf("internalContactInfo(%d): Too many responses (%d)", id, len(dbdata)) - } else if len(dbdata) == 0 { - return nil, nil - } else { - return &(dbdata[0]), nil - } + return &cinf, nil } return nil, err } diff --git a/database/globals.go b/database/globals.go index e2ea010..6711df5 100644 --- a/database/globals.go +++ b/database/globals.go @@ -12,7 +12,6 @@ package database import ( "context" "database/sql" - "errors" "sync" "git.erbosoft.com/amy/amsterdam/util" @@ -108,15 +107,12 @@ func AmGlobals(ctx context.Context) (*Globals, error) { globalsMutex.Lock() defer globalsMutex.Unlock() if theGlobals == nil { - var dbdata []Globals - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM globals") + var g Globals + err := amdb.GetContext(ctx, &g, "SELECT * FROM globals") if err != nil { return nil, err } - if len(dbdata) > 1 { - return nil, errors.New("should only be one globals record") - } - theGlobals = &(dbdata[0]) + theGlobals = &g } return theGlobals, nil } diff --git a/database/imagestore.go b/database/imagestore.go index 21b9b68..3fb67d4 100644 --- a/database/imagestore.go +++ b/database/imagestore.go @@ -12,7 +12,6 @@ package database import ( "context" "database/sql" - "fmt" ) // ImageStore is the structure for the image store table. @@ -61,17 +60,12 @@ func (img *ImageStore) Save(ctx context.Context) error { * Standard Go error status. */ func AmLoadImage(ctx context.Context, id int32) (*ImageStore, error) { - var dbdata []ImageStore - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM imagestore WHERE imgid = ?", id) + var imgdata ImageStore + err := amdb.GetContext(ctx, &imgdata, "SELECT * FROM imagestore WHERE imgid = ?", id) if err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("image ID %d not found", id) - } else if len(dbdata) > 1 { - return nil, fmt.Errorf("image ID %d too many images (%d)", id, len(dbdata)) - } - return &(dbdata[0]), nil + return &imgdata, nil } /* AmStoreImage stores an image in the database, overwriting one with the same type code and owner if it exists. diff --git a/database/ipban.go b/database/ipban.go index 2e48189..aadebbc 100644 --- a/database/ipban.go +++ b/database/ipban.go @@ -272,17 +272,12 @@ func AmListIPBans(ctx context.Context) ([]IPBanEntry, error) { // AmGetIPBan returns a single IP address ban structure. func AmGetIPBan(ctx context.Context, id int32) (*IPBanEntry, error) { - var dbdata []IPBanEntry - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM ipban WHERE id = ?", id) + var ban IPBanEntry + err := amdb.GetContext(ctx, &ban, "SELECT * FROM ipban WHERE id = ?", id) if err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, errors.New("not found") - } else if len(dbdata) > 1 { - return nil, errors.New("internal error, too many returns") - } - return &(dbdata[0]), nil + return &ban, nil } // AmAddIPBan adds a new IP address ban. diff --git a/database/post.go b/database/post.go index ae2f0be..bb8d3d0 100644 --- a/database/post.go +++ b/database/post.go @@ -236,17 +236,17 @@ func (p *PostHeader) PruneAttachment(ctx context.Context, u *User, comm *Communi // Text returns the text associated with a post. func (p *PostHeader) Text(ctx context.Context) (string, error) { - var dbdata []PostData - if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM postdata WHERE postid = ?", p.PostId); err != nil { + var pd PostData + if err := amdb.GetContext(ctx, &pd, "SELECT * FROM postdata WHERE postid = ?", p.PostId); err != nil { + if err == sql.ErrNoRows { + return "", ErrNoPostData + } return "", err } - if len(dbdata) > 1 { - return "", fmt.Errorf("too many data records (%d) for post #%d", len(dbdata), p.PostId) - } - if len(dbdata) == 0 || dbdata[0].Data == nil { + if pd.Data == nil { return "", ErrNoPostData } - return *dbdata[0].Data, nil + return *pd.Data, nil } // Link returns a link string to this post. @@ -514,17 +514,11 @@ func (p *PostHeader) MoveTo(ctx context.Context, target *Topic, u *User, comm *C * Standard Go error status. */ func AmGetPost(ctx context.Context, postId int64) (*PostHeader, error) { - var dbdata []PostHeader - if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE postid = ?", postId); err != nil { + var pd PostHeader + if err := amdb.GetContext(ctx, &pd, "SELECT * FROM posts WHERE postid = ?", postId); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, errors.New("post not found") - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetPost: too many entries (%d) for post ID %d", len(dbdata), postId) - } - return &(dbdata[0]), nil + return &pd, nil } /* AmGetPostRange gets a range of posts from a topic by post numbers. @@ -580,17 +574,11 @@ func AmNewPost(ctx context.Context, conf *Conference, topic *Topic, user *User, } // Read back the post header. - var dbdata []PostHeader - if err := tx.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE postid = ?", xid); err != nil { + var pd PostHeader + if err := tx.GetContext(ctx, &pd, "SELECT * FROM posts WHERE postid = ?", xid); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, errors.New("AmNewPost: new post not found") - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmNewPost: too many entries (%d) for post ID %d", len(dbdata), xid) - } - hdr := &(dbdata[0]) + hdr := &pd // Add the post data. _, err = tx.ExecContext(ctx, "INSERT INTO postdata (postid, data) VALUES (?, ?)", hdr.PostId, post) diff --git a/database/topic.go b/database/topic.go index c6484c8..91a6e00 100644 --- a/database/topic.go +++ b/database/topic.go @@ -65,16 +65,10 @@ func (t *Topic) GetPost(ctx context.Context, num int32) (*PostHeader, error) { if num > t.TopMessage { return nil, fmt.Errorf("no post %d in topic %d", num, t.TopicId) } - var dbdata []PostHeader - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE topicid = ? AND num = ?", t.TopicId, num) + var pd PostHeader + err := amdb.GetContext(ctx, &pd, "SELECT * FROM posts WHERE topicid = ? AND num = ?", t.TopicId, num) if err == nil { - if len(dbdata) == 0 { - err = fmt.Errorf("no post %d in topic %d", num, t.TopicId) - } else if len(dbdata) > 1 { - err = fmt.Errorf("topic.GetPost: too many entries (%d) for post %d in topic %d", len(dbdata), num, t.TopicId) - } else { - return &(dbdata[0]), nil - } + return &pd, nil } return nil, err } @@ -498,17 +492,11 @@ type TopicSummary struct { * Standard Go error status. */ func AmGetTopic(ctx context.Context, topicId int32) (*Topic, error) { - var dbdata []Topic - if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil { + var top Topic + if err := amdb.GetContext(ctx, &top, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("topic %d not found", topicId) - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetTopic(%d): too many responses (%d)", topicId, len(dbdata)) - } - return &(dbdata[0]), nil + return &top, nil } /* AmGetTopicTx retrieves a topic by ID, in a transaction. @@ -521,17 +509,11 @@ func AmGetTopic(ctx context.Context, topicId int32) (*Topic, error) { * Standard Go error status. */ func AmGetTopicTx(ctx context.Context, tx *sqlx.Tx, topicId int32) (*Topic, error) { - var dbdata []Topic - if err := tx.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil { + var top Topic + if err := tx.GetContext(ctx, &top, "SELECT * FROM topics WHERE topicid = ?", topicId); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, fmt.Errorf("topic %d not found", topicId) - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetTopic(%d): too many responses (%d)", topicId, len(dbdata)) - } - return &(dbdata[0]), nil + return &top, nil } /* AmGetTopicByNumber retrieves a topic by conference and sequence number. @@ -544,16 +526,10 @@ func AmGetTopicTx(ctx context.Context, tx *sqlx.Tx, topicId int32) (*Topic, erro * Standard Go error status. */ func AmGetTopicByNumber(ctx context.Context, conf *Conference, topicNum int16) (*Topic, error) { - var dbdata []Topic - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE confid = ? AND num = ?", conf.ConfId, topicNum) + var top Topic + err := amdb.GetContext(ctx, &top, "SELECT * FROM topics WHERE confid = ? AND num = ?", conf.ConfId, topicNum) if err == nil { - if len(dbdata) == 0 { - err = fmt.Errorf("no topic numbered %d in conference %s (#%d)", topicNum, conf.Name, conf.ConfId) - } else if len(dbdata) > 1 { - err = fmt.Errorf("AmGetTopicByNumber: too many entries (%d) for topic #%d in conference %s (#%d)", len(dbdata), topicNum, conf.Name, conf.ConfId) - } else { - return &(dbdata[0]), nil - } + return &top, nil } return nil, err } diff --git a/database/user.go b/database/user.go index a566246..3bceff7 100644 --- a/database/user.go +++ b/database/user.go @@ -62,14 +62,12 @@ func (p *UserPrefs) Save(ctx context.Context, u, setter *User, ipaddr string) er } var old *UserPrefs if setter.Uid != u.Uid { - var dbdata []UserPrefs - err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid) + var pref UserPrefs + err := amdb.GetContext(ctx, &pref, "SELECT * FROM userprefs WHERE uid = ?", u.Uid) if err != nil { return err - } else if len(dbdata) != 1 { - return errors.New("unable to take snapshot") } - old = &(dbdata[0]) + old = &pref } _, err := amdb.NamedExecContext(ctx, "UPDATE userprefs SET localeid = :localeid, tzid = :tzid WHERE uid = :uid", p) if err == nil && u != nil { @@ -349,14 +347,11 @@ func (u *User) Prefs(ctx context.Context) (*UserPrefs, error) { u.Mutex.Lock() defer u.Mutex.Unlock() if u.prefs == nil { - var dbdata []UserPrefs - if err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid); err != nil { + var pref UserPrefs + if err := amdb.GetContext(ctx, &pref, "SELECT * FROM userprefs WHERE uid = ?", u.Uid); err != nil { return nil, err } - if len(dbdata) != 1 { - return nil, fmt.Errorf("invalid preferences records for user %d", u.Uid) - } - u.prefs = &(dbdata[0]) + u.prefs = &pref } return u.prefs, nil } @@ -444,14 +439,11 @@ func AmGetUser(ctx context.Context, uid int32) (*User, error) { defer getUserMutex.Unlock() rc, ok := userCache.Get(uid) if !ok { - var dbdata []User - if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid); err != nil { + var user User + if err = amdb.GetContext(ctx, &user, "SELECT * from users WHERE uid = ?", uid); err != nil { return nil, err } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetUser(%d): too many responses(%d)", uid, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &user userCache.Add(uid, rc) } return rc.(*User), err @@ -472,14 +464,11 @@ func AmGetUserTx(ctx context.Context, tx *sqlx.Tx, uid int32) (*User, error) { defer getUserMutex.Unlock() rc, ok := userCache.Get(uid) if !ok { - var dbdata []User - if err = tx.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid); err != nil { + var user User + if err = tx.GetContext(ctx, &user, "SELECT * from users WHERE uid = ?", uid); err != nil { return nil, err } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetUser(%d): too many responses(%d)", uid, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &user userCache.Add(uid, rc) } return rc.(*User), err @@ -495,26 +484,21 @@ func AmGetUserTx(ctx context.Context, tx *sqlx.Tx, uid int32) (*User, error) { * Standard Go error status */ func AmGetUserByName(ctx context.Context, name string, tx *sqlx.Tx) (*User, error) { - var dbdata []User + var user User var err error if tx != nil { - err = tx.SelectContext(ctx, &dbdata, "SELECT * FROM users WHERE username = ?", name) + err = tx.GetContext(ctx, &user, "SELECT * FROM users WHERE username = ?", name) } else { - err = amdb.SelectContext(ctx, &dbdata, "SELECT * FROM users WHERE username = ?", name) + err = amdb.GetContext(ctx, &user, "SELECT * FROM users WHERE username = ?", name) } if err != nil { return nil, err } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetUserByName(\"%s\"): too many responses(%d)", name, len(dbdata)) - } else if len(dbdata) == 0 { - return nil, errors.New("user not found") - } getUserMutex.Lock() - rc, ok := userCache.Get(dbdata[0].Uid) + rc, ok := userCache.Get(user.Uid) if !ok { - rc = &(dbdata[0]) - userCache.Add(dbdata[0].Uid, rc) + rc = &user + userCache.Add(user.Uid, rc) } getUserMutex.Unlock() return rc.(*User), nil @@ -797,17 +781,11 @@ func internalGetProp(ctx context.Context, uid int32, ndx int32) (*UserProperties defer getUserPropMutex.Unlock() rc, ok := userPropCache.Get(key) if !ok { - var dbdata []UserProperties - if err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx); err != nil { + var prop UserProperties + if err = amdb.GetContext(ctx, &prop, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx); err != nil { return nil, err } - if len(dbdata) == 0 { - return nil, nil - } - if len(dbdata) > 1 { - return nil, fmt.Errorf("AmGetUserProperty(%d): too many responses(%d)", uid, len(dbdata)) - } - rc = &(dbdata[0]) + rc = &prop userPropCache.Add(key, rc) } return rc.(*UserProperties), nil