Added New Db Stuff
This commit is contained in:
76
events/ready/db-status.js
Normal file
76
events/ready/db-status.js
Normal file
@ -0,0 +1,76 @@
|
||||
const { Pool } = require('pg');
|
||||
|
||||
const cache = {
|
||||
global: [],
|
||||
byGuild: new Map(), // guildId -> rows[]
|
||||
ready: false
|
||||
};
|
||||
|
||||
function inWindow(row, now = new Date()) {
|
||||
if (row.starts_at && now < new Date(row.starts_at)) return false;
|
||||
if (row.ends_at && now > new Date(row.ends_at)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function pickWeighted(list) {
|
||||
if (!list.length) return null;
|
||||
const total = list.reduce((a, r) => a + (r.weight || 1), 0);
|
||||
let rnd = Math.random() * total;
|
||||
for (const r of list) {
|
||||
rnd -= (r.weight || 1);
|
||||
if (rnd <= 0) return r;
|
||||
}
|
||||
return list[0];
|
||||
}
|
||||
|
||||
async function loadAll(pool) {
|
||||
const { rows } = await pool.query(
|
||||
`SELECT id, name, activity_type, enabled, weight, scope, guild_id, starts_at, ends_at
|
||||
FROM bot_statuses
|
||||
WHERE enabled = TRUE`
|
||||
);
|
||||
|
||||
const now = new Date();
|
||||
cache.global = rows.filter(r => r.scope === 'global' && inWindow(r, now));
|
||||
cache.byGuild.clear();
|
||||
for (const r of rows) {
|
||||
if (r.scope === 'guild' && inWindow(r, now) && r.guild_id) {
|
||||
const arr = cache.byGuild.get(r.guild_id) || [];
|
||||
arr.push(r);
|
||||
cache.byGuild.set(r.guild_id, arr);
|
||||
}
|
||||
}
|
||||
cache.ready = true;
|
||||
}
|
||||
|
||||
async function initStatusCache(pool) {
|
||||
await loadAll(pool);
|
||||
|
||||
// Live refresh when table changes (if you created the trigger)
|
||||
const client = await pool.connect();
|
||||
await client.query('LISTEN status_change');
|
||||
client.on('notification', async () => {
|
||||
try {
|
||||
await loadAll(pool);
|
||||
console.log('[status] cache refreshed via NOTIFY');
|
||||
} catch (e) {
|
||||
console.error('[status] refresh error:', e);
|
||||
}
|
||||
});
|
||||
|
||||
// Safety: periodic refresh in case NOTIFY is missed
|
||||
setInterval(() => loadAll(pool).catch(() => {}), 5 * 60 * 1000);
|
||||
}
|
||||
|
||||
function getNextStatus(guildId) {
|
||||
const rows = (guildId && cache.byGuild.get(guildId))?.length
|
||||
? cache.byGuild.get(guildId)
|
||||
: cache.global;
|
||||
|
||||
return pickWeighted(rows || []);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
initStatusCache,
|
||||
getNextStatus
|
||||
};
|
||||
Reference in New Issue
Block a user