new comments
This commit is contained in:
parent
b2f649a489
commit
09404da121
13 changed files with 430 additions and 70 deletions
44
db.py
44
db.py
|
|
@ -1,12 +1,20 @@
|
|||
"""SQLite3 helper module for local telemetry storage.
|
||||
|
||||
Provides functions to initialize the local database schema and save
|
||||
telemetry snapshots into history and live_state tables.
|
||||
Enforces WAL mode, size limits, and auto-vacuum for efficient storage.
|
||||
"""
|
||||
import os
|
||||
import sqlite3
|
||||
from typing import Dict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Local SQLite database file name (used when running without TimescaleDB)
|
||||
DB_FILE = "dereth.db"
|
||||
# Maximum allowed database size (in MB). Defaults to 2048 (2GB). Override via env DB_MAX_SIZE_MB.
|
||||
MAX_DB_SIZE_MB = int(os.getenv("DB_MAX_SIZE_MB", "2048"))
|
||||
# Retention window for telemetry history in days. Override via env DB_RETENTION_DAYS.
|
||||
# Retention window for telemetry history in days (currently not auto-enforced).
|
||||
# Override via env DB_RETENTION_DAYS for future cleanup scripts.
|
||||
MAX_RETENTION_DAYS = int(os.getenv("DB_RETENTION_DAYS", "7"))
|
||||
# SQLite runtime limits customization
|
||||
DB_MAX_SQL_LENGTH = int(os.getenv("DB_MAX_SQL_LENGTH", "1000000000"))
|
||||
|
|
@ -16,8 +24,15 @@ DB_WAL_AUTOCHECKPOINT_PAGES = int(os.getenv("DB_WAL_AUTOCHECKPOINT_PAGES", "1000
|
|||
|
||||
|
||||
def init_db() -> None:
|
||||
"""Create tables if they do not exist (extended with kills_per_hour and onlinetime)."""
|
||||
"""
|
||||
Initialize local SQLite database schema for telemetry logging.
|
||||
|
||||
- Applies SQLite PRAGMA settings for performance and file size management
|
||||
- Ensures WAL journaling and auto-vacuum for concurrency and compaction
|
||||
- Creates telemetry_log for full history and live_state for latest snapshot per character
|
||||
"""
|
||||
# Open connection with a longer timeout
|
||||
# Open connection with extended timeout for schema operations
|
||||
conn = sqlite3.connect(DB_FILE, timeout=30)
|
||||
# Bump SQLite runtime limits
|
||||
conn.setlimit(sqlite3.SQLITE_LIMIT_LENGTH, DB_MAX_SQL_LENGTH)
|
||||
|
|
@ -25,16 +40,20 @@ def init_db() -> None:
|
|||
conn.setlimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, DB_MAX_SQL_VARIABLES)
|
||||
c = conn.cursor()
|
||||
# Enable auto_vacuum FULL and rebuild DB so that deletions shrink the file
|
||||
# Enable full auto-vacuum to shrink database file on deletes
|
||||
c.execute("PRAGMA auto_vacuum=FULL;")
|
||||
conn.commit()
|
||||
# Rebuild database to apply auto_vacuum changes
|
||||
c.execute("VACUUM;")
|
||||
conn.commit()
|
||||
# Switch to WAL mode for concurrency, adjust checkpointing, and enforce max size
|
||||
# Configure write-ahead logging for concurrency and performance
|
||||
c.execute("PRAGMA journal_mode=WAL")
|
||||
c.execute("PRAGMA synchronous=NORMAL")
|
||||
# Auto-checkpoint after specified WAL frames to limit WAL file size
|
||||
c.execute(f"PRAGMA wal_autocheckpoint={DB_WAL_AUTOCHECKPOINT_PAGES}")
|
||||
|
||||
# History log
|
||||
# Create history log table for all telemetry snapshots
|
||||
c.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS telemetry_log (
|
||||
|
|
@ -57,7 +76,7 @@ def init_db() -> None:
|
|||
"""
|
||||
)
|
||||
|
||||
# Live snapshot (upsert)
|
||||
# Create live_state table for upserts of the most recent snapshot per character
|
||||
c.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS live_state (
|
||||
|
|
@ -84,20 +103,27 @@ def init_db() -> None:
|
|||
|
||||
|
||||
def save_snapshot(data: Dict) -> None:
|
||||
"""Insert snapshot into history and upsert into live_state (with new fields)."""
|
||||
# Open connection with a longer busy timeout
|
||||
"""
|
||||
Save a telemetry snapshot into the local SQLite database.
|
||||
|
||||
Inserts a full record into telemetry_log (history) and upserts into live_state
|
||||
for quick lookup of the most recent data per character.
|
||||
|
||||
Respects WAL mode and checkpoint settings on each connection.
|
||||
"""
|
||||
# Open new connection with extended timeout for inserting data
|
||||
conn = sqlite3.connect(DB_FILE, timeout=30)
|
||||
# Bump SQLite runtime limits on this connection
|
||||
conn.setlimit(sqlite3.SQLITE_LIMIT_LENGTH, DB_MAX_SQL_LENGTH)
|
||||
conn.setlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH, DB_MAX_SQL_LENGTH)
|
||||
conn.setlimit(sqlite3.SQLITE_LIMIT_VARIABLE_NUMBER, DB_MAX_SQL_VARIABLES)
|
||||
c = conn.cursor()
|
||||
# Ensure WAL mode, checkpointing, and size limit on this connection
|
||||
# Ensure WAL mode and checkpointing settings on this connection
|
||||
c.execute("PRAGMA journal_mode=WAL")
|
||||
c.execute("PRAGMA synchronous=NORMAL")
|
||||
c.execute(f"PRAGMA wal_autocheckpoint={DB_WAL_AUTOCHECKPOINT_PAGES}")
|
||||
|
||||
# Insert full history row
|
||||
# Insert the snapshot into the telemetry_log (history) table
|
||||
c.execute(
|
||||
"""
|
||||
INSERT INTO telemetry_log (
|
||||
|
|
@ -125,7 +151,7 @@ def save_snapshot(data: Dict) -> None:
|
|||
),
|
||||
)
|
||||
|
||||
# Upsert into live_state
|
||||
# Upsert (insert or update) the latest snapshot into live_state table
|
||||
c.execute(
|
||||
"""
|
||||
INSERT INTO live_state (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue