91 lines
2.3 KiB
Go
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)
|
|
}
|