224 lines
8.2 KiB
Python
224 lines
8.2 KiB
Python
"""
|
|
Database initialization script for MTG Online backend.
|
|
|
|
Creates all necessary tables matching the SQLAlchemy ORM models
|
|
for both databases.
|
|
"""
|
|
import asyncio
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
from sqlalchemy import text
|
|
from app.core.settings import get_settings
|
|
|
|
|
|
async def setup_mtg_online_database():
|
|
"""Create tables for the mtgonline database."""
|
|
settings = get_settings()
|
|
engine = create_async_engine(settings.MTGO_DATABASE_URL)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as session:
|
|
# Create tables
|
|
tables = [
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_users (
|
|
id SERIAL PRIMARY KEY,
|
|
username VARCHAR(64) UNIQUE NOT NULL,
|
|
password_hash VARCHAR(128) NOT NULL,
|
|
salt VARCHAR(128) NOT NULL,
|
|
email VARCHAR(255),
|
|
country VARCHAR(2),
|
|
real_name VARCHAR(128),
|
|
avatar_bmp TEXT,
|
|
privlevel VARCHAR(50) DEFAULT 'User',
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
is_banned BOOLEAN DEFAULT FALSE,
|
|
ban_reason TEXT,
|
|
ban_ends TIMESTAMP,
|
|
vip_status INTEGER DEFAULT 0,
|
|
vip_expiry TIMESTAMP,
|
|
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
last_login TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_decklist_folders (
|
|
id SERIAL PRIMARY KEY,
|
|
owner_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
parent_id INTEGER REFERENCES mtgonline_decklist_folders(id) ON DELETE CASCADE,
|
|
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_decklist_files (
|
|
id SERIAL PRIMARY KEY,
|
|
folder_id INTEGER REFERENCES mtgonline_decklist_folders(id) ON DELETE CASCADE,
|
|
owner_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
content TEXT NOT NULL,
|
|
format VARCHAR(50) DEFAULT 'native',
|
|
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_rooms (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(100) UNIQUE NOT NULL,
|
|
description TEXT,
|
|
is_password_protected BOOLEAN DEFAULT FALSE,
|
|
password_hash VARCHAR(128),
|
|
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_rooms_gametypes (
|
|
id SERIAL PRIMARY KEY,
|
|
room_id INTEGER REFERENCES mtgonline_rooms(id) ON DELETE CASCADE,
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_bans (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
|
|
server_id INTEGER,
|
|
reason TEXT NOT NULL,
|
|
moderators VARCHAR(255),
|
|
ip_address VARCHAR(45),
|
|
expiration_time TIMESTAMP,
|
|
active BOOLEAN DEFAULT TRUE,
|
|
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_log (
|
|
id SERIAL PRIMARY KEY,
|
|
room_id INTEGER REFERENCES mtgonline_rooms(id) ON DELETE CASCADE,
|
|
player_id INTEGER REFERENCES mtgonline_users(id) ON DELETE CASCADE,
|
|
message TEXT NOT NULL,
|
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtgonline_audit (
|
|
id SERIAL PRIMARY KEY,
|
|
admin_id INTEGER REFERENCES mtgonline_users(id) ON DELETE SET NULL,
|
|
action_type VARCHAR(50) NOT NULL,
|
|
target_user_id INTEGER REFERENCES mtgonline_users(id) ON DELETE SET NULL,
|
|
details TEXT,
|
|
ip_address VARCHAR(45),
|
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
]
|
|
|
|
for table_sql in tables:
|
|
await session.execute(text(table_sql))
|
|
|
|
# Create indexes
|
|
indexes = [
|
|
"CREATE INDEX IF NOT EXISTS idx_decks_owner ON mtgonline_decklist_files(owner_id);",
|
|
"CREATE INDEX IF NOT EXISTS idx_decks_folder ON mtgonline_decklist_files(folder_id);",
|
|
"CREATE INDEX IF NOT EXISTS idx_bans_active ON mtgonline_bans(active);",
|
|
"CREATE INDEX IF NOT EXISTS idx_log_timestamp ON mtgonline_log(timestamp);",
|
|
]
|
|
|
|
for idx_sql in indexes:
|
|
await session.execute(text(idx_sql))
|
|
|
|
print("✓ All mtgonline tables created")
|
|
|
|
await engine.dispose()
|
|
|
|
|
|
async def setup_mtg_data_database():
|
|
"""Create tables for the mtgdata database."""
|
|
settings = get_settings()
|
|
engine = create_async_engine(settings.MTG_DATABASE_URL)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as session:
|
|
# Create tables
|
|
tables = [
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtg_sets (
|
|
id SERIAL PRIMARY KEY,
|
|
code VARCHAR(10) UNIQUE NOT NULL,
|
|
name VARCHAR(255),
|
|
type VARCHAR(100),
|
|
release_date DATE,
|
|
base_set_size INTEGER,
|
|
total_size INTEGER,
|
|
is_foil_only BOOLEAN,
|
|
is_non_foil_only BOOLEAN,
|
|
digital BOOLEAN,
|
|
icon_svg_url TEXT,
|
|
parent_code VARCHAR(10),
|
|
mtgo_code VARCHAR(10),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS mtg_cards (
|
|
id SERIAL PRIMARY KEY,
|
|
set_id INTEGER REFERENCES mtg_sets(id) ON DELETE CASCADE,
|
|
name VARCHAR(255),
|
|
mana_cost VARCHAR(255),
|
|
type_line VARCHAR(255),
|
|
oracle_text TEXT,
|
|
power VARCHAR(50),
|
|
toughness VARCHAR(50),
|
|
rarity VARCHAR(50),
|
|
layout VARCHAR(50),
|
|
artist VARCHAR(255),
|
|
flavor_text TEXT,
|
|
numbers VARCHAR(100),
|
|
identifiers TEXT,
|
|
images TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""",
|
|
]
|
|
|
|
for table_sql in tables:
|
|
await session.execute(text(table_sql))
|
|
|
|
# Create indexes
|
|
indexes = [
|
|
"CREATE INDEX IF NOT EXISTS idx_mtg_cards_name ON mtg_cards(name);",
|
|
"CREATE INDEX IF NOT EXISTS idx_mtg_cards_type ON mtg_cards(type_line);",
|
|
"CREATE INDEX IF NOT EXISTS idx_mtg_cards_rarity ON mtg_cards(rarity);",
|
|
"CREATE INDEX IF NOT EXISTS idx_mtg_cards_set_id ON mtg_cards(set_id);",
|
|
]
|
|
|
|
for idx_sql in indexes:
|
|
await session.execute(text(idx_sql))
|
|
|
|
print("✓ All mtgdata tables created")
|
|
|
|
await engine.dispose()
|
|
|
|
|
|
async def main():
|
|
"""Main initialization function."""
|
|
print("MTG Online Database Initialization")
|
|
print("=" * 50)
|
|
|
|
# Setup mtgonline database
|
|
print("\nSetting up mtgonline database...")
|
|
await setup_mtg_online_database()
|
|
|
|
# Setup mtgdata database
|
|
print("\nSetting up mtgdata database...")
|
|
await setup_mtg_data_database()
|
|
|
|
print("\n✓ Database initialization complete!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|