Files
amsterdam/database/hotlist.go
T

148 lines
4.6 KiB
Go

/*
* Amsterdam Web Communities System
* Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
// The database package contains database management and storage logic.
package database
import (
"context"
"database/sql"
"errors"
)
// ConferenceHotlist represents a user's conference hotlist.
type ConferenceHotlist struct {
Uid int32 `db:"uid"`
Sequence int16 `db:"sequence"`
CommId int32 `db:"commid"`
ConfId int32 `db:"confid"`
}
const HOTLIST_SEQUENCE_SPACING = 100
// Community gets the community pointer from the hotlist.
func (h *ConferenceHotlist) Community(ctx context.Context) (*Community, error) {
return AmGetCommunity(ctx, h.CommId)
}
// Conference gets the conference pointer from the hotlist.
func (h *ConferenceHotlist) Conference(ctx context.Context) (*Conference, error) {
return AmGetConference(ctx, h.ConfId)
}
// AmGetConferenceHotlist gets the conference hotlist for a user.
func AmGetConferenceHotlist(ctx context.Context, u *User) ([]ConferenceHotlist, error) {
var rc []ConferenceHotlist
err := amdb.SelectContext(ctx, &rc, "SELECT * FROM confhotlist WHERE uid = ? ORDER BY sequence", u.Uid)
return rc, err
}
// AmCopyConferenceHotlist copies the conference hotlist from one user to another.
func AmCopyConferenceHotlist(ctx context.Context, from, to *User) error {
hotlist, err := AmGetConferenceHotlist(ctx, from)
if err != nil {
return err
}
tx, commit, rollback := transaction(ctx)
defer rollback()
for _, hl := range hotlist {
if _, err = tx.ExecContext(ctx, "INSERT INTO confhotlist (uid, sequence, commid, confid) VALUES (?, ?, ?, ?)",
to.Uid, hl.Sequence, hl.CommId, hl.ConfId); err != nil {
return err
}
}
if err = commit(); err != nil {
return err
}
return nil
}
// AmReorderHotlist exchanges the position of two items on the user's hotlist.
func AmReorderHotlist(ctx context.Context, u *User, seq1, seq2 int16) error {
tx, commit, rollback := transaction(ctx)
defer rollback()
_, err := tx.ExecContext(ctx, "UPDATE confhotlist SET sequence = -1 WHERE uid = ? AND sequence = ?", u.Uid, seq1)
if err == nil {
_, err = tx.ExecContext(ctx, "UPDATE confhotlist SET sequence = ? WHERE uid = ? AND sequence = ?", seq1, u.Uid, seq2)
if err == nil {
_, err = tx.ExecContext(ctx, "UPDATE confhotlist SET sequence = ? WHERE uid = ? AND sequence = -1", seq2, u.Uid)
}
}
if err != nil {
return err
}
if err = commit(); err != nil {
return err
}
return nil
}
// AmRemoveEntryFromHotlist removes an entry from the user's hotlist.
func AmRemoveEntryFromHotlist(ctx context.Context, u *User, seq int16) error {
tx, commit, rollback := transaction(ctx)
defer rollback()
_, err := tx.ExecContext(ctx, "DELETE FROM confhotlist WHERE uid = ? AND sequence = ?", u.Uid, seq)
if err == nil {
_, err = tx.ExecContext(ctx, "UPDATE confhotlist SET sequence = sequence - ? WHERE uid = ? AND sequence > ?", HOTLIST_SEQUENCE_SPACING, u.Uid, seq)
}
if err != nil {
return err
}
if err = commit(); err != nil {
return err
}
return nil
}
// AmAppendToHotlist adds a community/conference ID to the end of the user's hotlist.
func AmAppendToHotlist(ctx context.Context, u *User, commid, confid int32) error {
tx, commit, rollback := transaction(ctx)
defer rollback()
var newseq int16
err := tx.GetContext(ctx, &newseq, "SELECT sequence FROM confhotlist WHERE uid = ? AND commid = ? AND confid = ?", u.Uid, commid, confid)
if err == nil {
return errors.New("community/conference already exist in hotlist")
} else if err != sql.ErrNoRows {
return err
}
err = tx.GetContext(ctx, &newseq, "SELECT MAX(sequence) FROM confhotlist WHERE uid = ?", u.Uid)
if err == sql.ErrNoRows {
newseq = 0
} else if err != nil {
return err
}
_, err = tx.ExecContext(ctx, "INSERT INTO confhotlist (uid, sequence, commid, confid) VALUES (?, ?, ?, ?)",
u.Uid, newseq+HOTLIST_SEQUENCE_SPACING, commid, confid)
if err != nil {
return err
}
if err = commit(); err != nil {
return err
}
return nil
}
// AmIsInHotlist returns true if the community/conference pair is in the hotlist.
func AmIsInHotlist(ctx context.Context, u *User, commid, confid int32) (bool, error) {
var tmp int16
err := amdb.GetContext(ctx, &tmp, "SELECT sequence FROM confhotlist WHERE uid = ? AND commid = ? AND confid = ?", u.Uid, commid, confid)
switch err {
case nil:
return true, nil
case sql.ErrNoRows:
return false, nil
}
return false, err
}