Files
pyrom/app/schema.py
2025-12-02 06:13:50 +03:00

178 lines
7.2 KiB
Python

from .db import db
# list of statements
SCHEMA = [
"""CREATE TABLE IF NOT EXISTS "api_rate_limits" (
"id" INTEGER NOT NULL PRIMARY KEY,
"method" TEXT NOT NULL,
"user_id" INTEGER REFERENCES users(id) ON DELETE CASCADE,
"logged_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP))
)""",
"""CREATE TABLE IF NOT EXISTS "avatars" (
"id" INTEGER NOT NULL PRIMARY KEY,
"file_path" TEXT NOT NULL UNIQUE,
"uploaded_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP))
)""",
"""CREATE TABLE IF NOT EXISTS "post_history" (
"id" INTEGER NOT NULL PRIMARY KEY,
"post_id" INTEGER REFERENCES posts(id) ON DELETE CASCADE,
"content" TEXT NOT NULL,
"edited_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"is_initial_revision" BOOLEAN DEFAULT FALSE
, "original_markup" TEXT NOT NULL, "markup_language" TEXT NOT NULL DEFAULT 'babycode'
)""",
"""CREATE TABLE IF NOT EXISTS "posts" (
"id" INTEGER NOT NULL PRIMARY KEY,
"thread_id" INTEGER REFERENCES threads(id) ON DELETE CASCADE,
"user_id" INTEGER REFERENCES users(id) ON DELETE SET NULL,
"created_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"current_revision_id" INTEGER REFERENCES post_history(id)
)""",
"""CREATE TABLE IF NOT EXISTS "sessions" (
"id" INTEGER NOT NULL PRIMARY KEY,
"key" TEXT NOT NULL UNIQUE,
"user_id" INTEGER REFERENCES users(id) ON DELETE CASCADE,
"expires_at" INTEGER NOT NULL,
"created_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP))
)""",
"""CREATE TABLE IF NOT EXISTS "subscriptions" (
"id" INTEGER NOT NULL PRIMARY KEY,
"user_id" INTEGER REFERENCES users(id) ON DELETE CASCADE,
"thread_id" INTEGER REFERENCES threads(id) ON DELETE CASCADE,
"last_seen" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)) NOT NULL
)""",
"""CREATE TABLE IF NOT EXISTS "threads" (
"id" INTEGER NOT NULL PRIMARY KEY,
"topic_id" INTEGER REFERENCES topics(id) ON DELETE CASCADE,
"user_id" INTEGER REFERENCES users(id) ON DELETE SET NULL,
"title" TEXT NOT NULL,
"slug" TEXT NOT NULL UNIQUE,
"created_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"is_locked" BOOLEAN DEFAULT FALSE, "is_stickied" BOOLEAN DEFAULT FALSE
)""",
"""CREATE TABLE IF NOT EXISTS "topics" (
"id" INTEGER NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"slug" TEXT NOT NULL UNIQUE,
"description" TEXT NOT NULL DEFAULT '', "is_locked" BOOLEAN DEFAULT FALSE, "sort_order" INTEGER NOT NULL DEFAULT 0
)""",
"""CREATE TABLE IF NOT EXISTS "users" (
"id" INTEGER NOT NULL PRIMARY KEY,
"username" TEXT NOT NULL UNIQUE,
"password_hash" TEXT NOT NULL,
"permission" INTEGER NOT NULL DEFAULT 0,
"created_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"confirmed_on" INTEGER, "status" TEXT DEFAULT '',
"avatar_id" REFERENCES avatars(id) DEFAULT 1,
"signature_original_markup" TEXT NOT NULL DEFAULT '',
"signature_rendered" TEXT NOT NULL DEFAULT ''
)""",
"""CREATE TABLE IF NOT EXISTS "reactions" (
"id" INTEGER NOT NULL PRIMARY KEY,
"user_id" REFERENCES users(id) ON DELETE CASCADE,
"post_id" REFERENCES posts(id) ON DELETE CASCADE,
"reaction_text" TEXT NOT NULL DEFAULT ''
)""",
"""CREATE TABLE IF NOT EXISTS "password_reset_links" (
"id" INTEGER NOT NULL PRIMARY KEY,
"user_id" REFERENCES users(id) ON DELETE CASCADE,
"expires_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"key" TEXT NOT NULL UNIQUE
)""",
"""CREATE TABLE IF NOT EXISTS "invite_keys" (
"id" INTEGER NOT NULL PRIMARY KEY,
"created_by" REFERENCES users(id) ON DELETE CASCADE,
"key" TEXT NOT NULL UNIQUE
)""",
"""CREATE TABLE IF NOT EXISTS "bookmark_collections" (
"id" INTEGER NOT NULL PRIMARY KEY,
"user_id" REFERENCES users(id) ON DELETE CASCADE,
"name" TEXT NOT NULL,
"is_default" BOOLEAN NOT NULL DEFAULT FALSE,
"sort_order" INTEGER NOT NULL DEFAULT 0
)""",
"""CREATE TABLE IF NOT EXISTS "bookmarked_posts" (
"id" INTEGER NOT NULL PRIMARY KEY,
"collection_id" REFERENCES bookmark_collections(id) ON DELETE CASCADE,
"post_id" REFERENCES posts(id) ON DELETE CASCADE,
"note" TEXT,
UNIQUE(collection_id, post_id)
)""",
"""CREATE TABLE IF NOT EXISTS "bookmarked_threads" (
"id" INTEGER NOT NULL PRIMARY KEY,
"collection_id" REFERENCES bookmark_collections(id) ON DELETE CASCADE,
"thread_id" REFERENCES threads(id) ON DELETE CASCADE,
"note" TEXT,
UNIQUE(collection_id, thread_id)
)""",
"""CREATE TABLE IF NOT EXISTS "motd" (
"id" INTEGER NOT NULL PRIMARY KEY,
"title" TEXT NOT NULL,
"body_original_markup" TEXT NOT NULL,
"body_rendered" TEXT NOT NULL,
"markup_language" TEXT NOT NULL DEFAULT 'babycode',
"format_version" INTEGER DEFAULT NULL,
"created_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"edited_at" INTEGER DEFAULT (unixepoch(CURRENT_TIMESTAMP)),
"user_id" REFERENCES users(id) ON DELETE CASCADE
)""",
"""CREATE TABLE IF NOT EXISTS "mentions" (
"id" INTEGER NOT NULL PRIMARY KEY,
"revision_id" REFERENCES post_history(id) ON DELETE CASCADE,
"mentioned_user_id" REFERENCES users(id) ON DELETE CASCADE,
"start_index" INTEGER NOT NULL,
"end_index" INTEGER NOT NULL,
"original_mention_text" TEXT NOT NULL
)""",
# INDEXES
"CREATE INDEX IF NOT EXISTS idx_post_history_post_id ON post_history(post_id)",
"CREATE INDEX IF NOT EXISTS idx_posts_thread ON posts(thread_id, created_at, id)",
"CREATE INDEX IF NOT EXISTS idx_posts_thread_id ON posts(thread_id)",
"CREATE INDEX IF NOT EXISTS idx_rate_limit_user_method ON api_rate_limits (user_id, method)",
"CREATE INDEX IF NOT EXISTS idx_subscription_user_thread ON subscriptions (user_id, thread_id)",
"CREATE INDEX IF NOT EXISTS idx_threads_slug ON threads(slug)",
"CREATE INDEX IF NOT EXISTS idx_threads_topic_id ON threads(topic_id)",
"CREATE INDEX IF NOT EXISTS idx_topics_slug ON topics(slug)",
"CREATE INDEX IF NOT EXISTS session_keys ON sessions(key)",
"CREATE INDEX IF NOT EXISTS sessions_user_id ON sessions(user_id)",
"CREATE INDEX IF NOT EXISTS reaction_post_text ON reactions(post_id, reaction_text)",
"CREATE INDEX IF NOT EXISTS reaction_user_post_text ON reactions(user_id, post_id, reaction_text)",
"CREATE INDEX IF NOT EXISTS idx_bookmark_collections_user_id ON bookmark_collections(user_id)",
"CREATE INDEX IF NOT EXISTS idx_bookmark_collections_user_default ON bookmark_collections(user_id, is_default) WHERE is_default = 1",
"CREATE INDEX IF NOT EXISTS idx_bookmarked_posts_collection ON bookmarked_posts(collection_id)",
"CREATE INDEX IF NOT EXISTS idx_bookmarked_posts_post ON bookmarked_posts(post_id)",
"CREATE INDEX IF NOT EXISTS idx_bookmarked_threads_collection ON bookmarked_threads(collection_id)",
"CREATE INDEX IF NOT EXISTS idx_bookmarked_threads_thread ON bookmarked_threads(thread_id)",
"CREATE INDEX IF NOT EXISTS idx_mentioned_user ON mentions(mentioned_user_id)",
"CREATE INDEX IF NOT EXISTS idx_mention_revision_id ON mentions(revision_id)",
]
def create():
print("Creating schema...")
with db.transaction():
for stmt in SCHEMA:
db.execute(stmt)
print("Schema completed.")