Files
amsterdam/database/adverts.go
T

91 lines
2.3 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"
crand "crypto/rand"
"math/big"
"sync"
"git.erbosoft.com/amy/amsterdam/config"
lru "github.com/hashicorp/golang-lru"
)
// Advert represents an advertising banner.
type Advert struct {
AdId int32 `db:"adid"` // ID of the ad
ImagePath string `db:"imagepath"` // path to the ad image
PathStyle int16 `db:"pathstyle"` // path style
Caption *string `db:"caption"` // caption
LinkURL *string `db:"linkurl"` // link URL
}
// Values for PathStyle.
const (
AdPathStyleContextRelative int16 = 0 // indicates context-relative image path
)
// adCache is the cache for advertisements.
var adCache *lru.Cache = nil
// adCacheMutex synchronizes access to adCache.
var adCacheMutex sync.Mutex
// setupAdCache sets up the ad cache.
func setupAdCache() {
var err error
adCache, err = lru.New(config.GlobalConfig.Tuning.Caches.Ads)
if err != nil {
panic(err)
}
}
// ResolvePath creates an absolute image path based on the stored path data.
func (ad *Advert) ResolvePath() string {
if ad.PathStyle == AdPathStyleContextRelative {
return "/" + ad.ImagePath
}
return ""
}
// AmGetAd gets an ad by ID.
func AmGetAd(ctx context.Context, adid int32) (*Advert, error) {
adCacheMutex.Lock()
defer adCacheMutex.Unlock()
rc, ok := adCache.Get(adid)
if ok {
return rc.(*Advert), nil
}
theAd := new(Advert)
err := amdb.GetContext(ctx, theAd, "SELECT * FROM adverts WHERE adid = ?", adid)
if err != nil {
return nil, err
}
adCache.Add(adid, theAd)
return theAd, nil
}
// AmGetRandomAd gets a random ad from the
func AmGetRandomAd(ctx context.Context) (*Advert, error) {
var num int
err := amdb.GetContext(ctx, &num, "SELECT COUNT(*) FROM adverts")
if err != nil {
return nil, err
}
v1, err := crand.Int(crand.Reader, big.NewInt(int64(num)))
if err != nil {
return nil, err
}
return AmGetAd(ctx, int32(v1.Int64())+1)
}