v4.3: file-based media storage + manual VACUUM maintenance
This commit is contained in:
46
db.py
46
db.py
@@ -1,4 +1,4 @@
|
||||
# db.py - Database Configuration and Operations (v4.2)
|
||||
# db.py - Database Configuration and Operations (v4.3)
|
||||
|
||||
import os
|
||||
import sqlite3
|
||||
@@ -32,13 +32,19 @@ def get_db_connection():
|
||||
|
||||
|
||||
def init_db():
|
||||
"""Initialize database tables. Auto-creates parent directory."""
|
||||
"""Initialize database tables. Auto-creates parent directory + media storage."""
|
||||
# ফোল্ডার না থাকলে নিজে থেকেই তৈরি করবে (Coolify volume mount-এর জন্য জরুরি)
|
||||
db_dir = os.path.dirname(os.path.abspath(DATABASE))
|
||||
if db_dir and not os.path.exists(db_dir):
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
print(f"📂 Created data directory: {db_dir}")
|
||||
|
||||
# v4.3: media-storage ফোল্ডার তৈরি
|
||||
from config import MEDIA_STORAGE_DIR
|
||||
if not os.path.exists(MEDIA_STORAGE_DIR):
|
||||
os.makedirs(MEDIA_STORAGE_DIR, exist_ok=True)
|
||||
print(f"📂 Created media storage directory: {MEDIA_STORAGE_DIR}")
|
||||
|
||||
with get_db_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
@@ -115,7 +121,7 @@ def init_db():
|
||||
)
|
||||
''')
|
||||
|
||||
# v4.2 publishing migrations
|
||||
# v4.2 publishing migrations + v4.3 file-based media path columns
|
||||
migrations = [
|
||||
('projects', 'is_published', 'INTEGER DEFAULT 0'),
|
||||
('projects', 'published_at', 'TIMESTAMP'),
|
||||
@@ -125,6 +131,10 @@ def init_db():
|
||||
('projects', 'author', 'TEXT DEFAULT ""'),
|
||||
('projects', 'category', 'TEXT DEFAULT ""'),
|
||||
('projects', 'view_count', 'INTEGER DEFAULT 0'),
|
||||
# --- v4.3: file-based media path columns ---
|
||||
('projects', 'thumbnail_path', 'TEXT'),
|
||||
('markdown_blocks', 'audio_path', 'TEXT'),
|
||||
('block_images', 'image_path', 'TEXT'),
|
||||
]
|
||||
|
||||
for table, column, definition in migrations:
|
||||
@@ -135,14 +145,42 @@ def init_db():
|
||||
pass
|
||||
|
||||
conn.commit()
|
||||
print(f"✅ Database initialized at {DATABASE} (v4.2)")
|
||||
print(f"✅ Database initialized at {DATABASE} (v4.3)")
|
||||
|
||||
|
||||
def vacuum_db():
|
||||
"""ম্যানুয়াল VACUUM (এখন আর অটোমেটিক চলে না)।"""
|
||||
with get_db_connection() as conn:
|
||||
conn.execute('VACUUM')
|
||||
|
||||
|
||||
def get_db_stats():
|
||||
"""
|
||||
ডেটাবেসের সাইজ এবং কত% ফাঁকা (reusable free) স্পেস আছে তা রিটার্ন করে।
|
||||
SQLite-এর freelist_count আর page_count দিয়ে হিসাব করা হয়।
|
||||
"""
|
||||
file_size = os.path.getsize(DATABASE) if os.path.exists(DATABASE) else 0
|
||||
with get_db_connection() as conn:
|
||||
cur = conn.cursor()
|
||||
page_count = cur.execute('PRAGMA page_count').fetchone()[0]
|
||||
freelist_count = cur.execute('PRAGMA freelist_count').fetchone()[0]
|
||||
page_size = cur.execute('PRAGMA page_size').fetchone()[0]
|
||||
|
||||
free_bytes = freelist_count * page_size
|
||||
free_percent = round((freelist_count / page_count) * 100, 1) if page_count > 0 else 0.0
|
||||
|
||||
return {
|
||||
'file_size_bytes': file_size,
|
||||
'file_size_mb': round(file_size / (1024 * 1024), 2),
|
||||
'page_count': page_count,
|
||||
'freelist_count': freelist_count,
|
||||
'page_size': page_size,
|
||||
'free_bytes': free_bytes,
|
||||
'free_mb': round(free_bytes / (1024 * 1024), 2),
|
||||
'free_percent': free_percent,
|
||||
}
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.teardown_appcontext(close_db)
|
||||
init_db()
|
||||
|
||||
Reference in New Issue
Block a user