diff --git a/db_async.py b/db_async.py index 8a5623e7..998d6707 100644 --- a/db_async.py +++ b/db_async.py @@ -9,6 +9,7 @@ from datetime import datetime, timedelta, timezone from databases import Database from sqlalchemy import MetaData, Table, Column, Integer, String, Float, DateTime, text from sqlalchemy import Index, BigInteger, JSON, Boolean, UniqueConstraint +from sqlalchemy.sql import func # Environment: Postgres/TimescaleDB connection URL DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:password@localhost:5432/dereth") @@ -175,6 +176,20 @@ Index( server_health_checks.c.timestamp.desc() ) +character_stats = Table( + "character_stats", + metadata, + Column("character_name", String, primary_key=True, nullable=False), + Column("timestamp", DateTime(timezone=True), nullable=False, server_default=func.now()), + Column("level", Integer, nullable=True), + Column("total_xp", BigInteger, nullable=True), + Column("unassigned_xp", BigInteger, nullable=True), + Column("luminance_earned", BigInteger, nullable=True), + Column("luminance_total", BigInteger, nullable=True), + Column("deaths", Integer, nullable=True), + Column("stats_data", JSON, nullable=False), +) + async def init_db_async(): """Initialize PostgreSQL/TimescaleDB schema and hypertable. @@ -250,6 +265,26 @@ async def init_db_async(): except Exception as e: print(f"Warning: failed to create portal table constraints: {e}") + # Ensure character_stats table exists with JSONB column type + try: + with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as conn: + conn.execute(text(""" + CREATE TABLE IF NOT EXISTS character_stats ( + character_name VARCHAR(255) PRIMARY KEY, + timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(), + level INTEGER, + total_xp BIGINT, + unassigned_xp BIGINT, + luminance_earned BIGINT, + luminance_total BIGINT, + deaths INTEGER, + stats_data JSONB NOT NULL + ) + """)) + print("character_stats table created/verified successfully") + except Exception as e: + print(f"Warning: failed to create character_stats table: {e}") + async def cleanup_old_portals(): """Clean up portals older than 1 hour.""" try: diff --git a/main.py b/main.py index f71f4dd5..3ddab2cc 100644 --- a/main.py +++ b/main.py @@ -37,6 +37,7 @@ from db_async import ( spawn_events, rare_events, character_inventories, + character_stats, portals, server_health_checks, server_status,