moving to postgres, part 2

This commit is contained in:
2025-09-17 23:16:29 +02:00
parent 223add151c
commit 2862aacc50
9 changed files with 45 additions and 48 deletions

View File

@@ -17,8 +17,11 @@ STREAMER_ID= # Twitch ID of the streaming user
CHATTER_ID= # Twitch ID of the chatting user
CHATTER_IS_STREAMER= # If the bot that activates on commands is on the same account as the streamer, set this to true. Make sure the STREAMER_ID and CHATTER_ID match in that case.
# Pocketbase config
# POCKETBASE_URL= # Pocketbase URL. Defaults to http://localhost:8090
# Postgres config
POSTGRES_HOST= # Hostname + port of the postgres database
POSTGRES_USER= # Username for logging in on the postgres database
POSTGRES_PASSWORD= # Password for logging in on the postgres database
POSTGRES_DB=twitchbot # Database name. Recommended value: twitchbot
# Redis/Valkey config
# REDIS_URL= # Redis URL. Defaults to redis://localhost:6379

3
.gitignore vendored
View File

@@ -24,6 +24,9 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
.env.production.local
.env.local
# Drizzle config files
*.config.ts
# caches
.eslintcache
.cache

View File

@@ -9,25 +9,12 @@ services:
- ./db/redis:/data
environment:
- VALKEY_EXTRA_FLAGS=--save 60 1
# pocketbase:
# container_name: qweribot-pocketbase
# build:
# context: ./pocketbase
# ports:
# - 8090:8090
# restart: no
# volumes:
# - ./db/pocketbase:/pb/pb_data
postgres:
container_name: postgres
image: postgres:latest
restart: unless-stopped
env_file:
- .env.development
# environment:
# POSTGRES_USER: $$POSTGRES_USER
# POSTGRES_PASSWORD: $$POSTGRES_PASSWORD
# POSTGRES_DB: $$POSTGRES_DB
ports:
- "5432:5432"
volumes:

View File

@@ -1,9 +0,0 @@
import { defineConfig } from "drizzle-kit";
const url = `postgresql://admin:abcdefgh@localhost:5432/twitchbot`;
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema.ts',
dbCredentials: { url }
});

View File

@@ -6,6 +6,14 @@
"drizzle-kit": "^0.31.4",
"pg": "^8.16.3"
},
"scripts": {
"start": "NODE_ENV=production bun src/index.ts",
"start-dev": "NODE_ENV=development bun src/index.ts",
"migrate": "drizzle-kit push --config=drizzle-prod.config.ts",
"migrate-dev": "drizzle-kit push --config=drizzle-dev.config.ts",
"studio": "drizzle-kit studio --config=drizzle-prod.config.ts",
"studio-dev": "drizzle-kit studio --config=drizzle-dev.config.ts"
},
"peerDependencies": {
"typescript": "^5.8.3"
},

View File

@@ -1,7 +1,7 @@
import { redis } from "bun";
import { Command, sendMessage } from "commands";
import { getUserRecord, updateUserRecord } from "db/dbUser";
import items, { type inventory, type items } from "items";
import itemMap, { type inventory, type items } from "items";
import { buildTimeString } from "lib/dateManager";
import { timeout } from "lib/timeout";
import { isInvuln, removeInvuln } from "lib/invuln";
@@ -59,7 +59,7 @@ export default new Command({
if (Math.floor(Math.random() * 250) === 0) itemDiff.silverbullet! += 1;
};
for (const [item, amount] of Object.entries(itemDiff) as [items, number]) {
for (const [item, amount] of Object.entries(itemDiff) as [items, number][]) {
if (userData.inventory[item]) userData.inventory[item] += amount;
else userData.inventory[item] = amount;
};
@@ -68,7 +68,7 @@ export default new Command({
for (const [item, amount] of Object.entries(itemDiff)) {
if (amount === 0) continue;
const selection = items.get(item);
const selection = itemMap.get(item);
if (!selection) continue;
itemstrings.push(`${amount} ${selection.prettyName + (amount === 1 ? '' : selection.plural)}`);
};

View File

@@ -1,10 +1,13 @@
import { RedisClient } from "bun";
import db from "db/connection";
import { users } from "db/schema";
import logger from "lib/logger";
export async function connectionCheck() {
let pbstatus = false;
let pgstatus = false;
try {
pbstatus = true;
await db.select().from(users); // The query doesn't matter, only that it fails. This also fails if the migration hasn't taken place
pgstatus = true;
} catch { };
const tempclient = new RedisClient(undefined, {
connectionTimeout: 100,
@@ -16,7 +19,7 @@ export async function connectionCheck() {
redisstatus = true;
} catch { };
logger.info(`Currently using the "${process.env.NODE_ENV ?? "production"}" database`);
pbstatus ? logger.ok(`Pocketbase status: good`) : logger.err(`Pocketbase status: bad`);
pgstatus ? logger.ok(`Postgresql status: good`) : logger.err(`Postgresql status: bad`);
redisstatus ? logger.ok(`Redis/Valkey status: good`) : logger.err(`Redis/Valkey status: bad`);
if (!pbstatus || !redisstatus) process.exit(1);
if (!pgstatus || !redisstatus) process.exit(1);
};

View File

@@ -1,18 +1,15 @@
import * as schema from "db/schema";
import logger from "lib/logger";
// const host = process.env.POSTGRES_HOST ?? "";
// if (!host) { logger.enverr("POSTGRES_HOST"); process.exit(1); };
//
// const user = process.env.POSTGRES_USER ?? "";
// if (!user) { logger.enverr("POSTGRES_USER"); process.exit(1); };
// const password = process.env.POSTGRES_PASSWORD ?? "";
// if (!password) { logger.enverr("POSTGRES_USER"); process.exit(1); };
// const database = process.env.POSTGRES_DB ?? "twitchbot";
//
// const connection = { host, user, password, database };
const url = `postgresql://admin:abcdefgh@localhost:5432/twitchbot`;
const host = process.env.POSTGRES_HOST ?? "";
if (!host) { logger.enverr("POSTGRES_HOST"); process.exit(1); };
const user = process.env.POSTGRES_USER ?? "";
if (!user) { logger.enverr("POSTGRES_USER"); process.exit(1); };
const password = process.env.POSTGRES_PASSWORD ?? "";
if (!password) { logger.enverr("POSTGRES_USER"); process.exit(1); };
const database = process.env.POSTGRES_DB ?? "";
if (!database) { logger.enverr("POSTGRES_DB"); process.exit(1); };
const url = `postgresql://${user}:${password}@${host}/${database}`;
import { drizzle } from 'drizzle-orm/bun-sql';
export default drizzle(url, {
schema
});
export default drizzle(url, { schema });

View File

@@ -40,7 +40,12 @@ export async function getItemStats(target: User, thismonth: boolean) {
]);
if (!items || !cheers) return;
const returnObj: inventory = {};
const returnObj: inventory = {
blaster: 0,
silverbullet: 0,
grenade: 0,
tnt: 0,
};
for (const item of items) {
if (!returnObj[item.item]) returnObj[item.item] = 0;
@@ -48,8 +53,8 @@ export async function getItemStats(target: User, thismonth: boolean) {
};
for (const cheer of cheers) {
if (!returnObj[cheer.cheer]) returnObj[cheer.cheer] = 0;
returnObj[cheer.cheer]! += 1
if (!returnObj[cheer.event]) returnObj[cheer.event] = 0;
returnObj[cheer.event]! += 1
};
return returnObj;