Standardize tenant DB directory to db with legacy migration
This commit is contained in:
@@ -53,16 +53,57 @@ WORKSPACE_DIR = os.path.join(ROOT_DIR, 'workspace')
|
||||
# Engine cache for multi-tenant support
|
||||
_user_engines = {}
|
||||
|
||||
|
||||
def _sanitize_user_id(user_id: str) -> str:
|
||||
"""Sanitize user_id to be safe for filesystem."""
|
||||
return "".join(c for c in user_id if c.isalnum() or c in ('-', '_'))
|
||||
|
||||
|
||||
def ensure_user_workspace_db_directory(user_id: str) -> str:
|
||||
"""Ensure modern `db/` directory exists, migrating legacy `database/` when safe."""
|
||||
safe_user_id = _sanitize_user_id(user_id)
|
||||
user_workspace = os.path.join(WORKSPACE_DIR, f"workspace_{safe_user_id}")
|
||||
db_dir = os.path.join(user_workspace, 'db')
|
||||
legacy_db_dir = os.path.join(user_workspace, 'database')
|
||||
|
||||
if os.path.isdir(legacy_db_dir) and not os.path.exists(db_dir):
|
||||
try:
|
||||
os.rename(legacy_db_dir, db_dir)
|
||||
logger.info(f"Migrated legacy database directory to db/: {user_workspace}")
|
||||
except OSError as rename_error:
|
||||
logger.warning(
|
||||
f"Could not rename legacy database directory for {user_workspace}: {rename_error}"
|
||||
)
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
for filename in os.listdir(legacy_db_dir):
|
||||
src = os.path.join(legacy_db_dir, filename)
|
||||
dst = os.path.join(db_dir, filename)
|
||||
if os.path.isfile(src) and not os.path.exists(dst):
|
||||
try:
|
||||
os.link(src, dst)
|
||||
except OSError:
|
||||
# Fall back to copy when hard-linking is not possible.
|
||||
import shutil
|
||||
shutil.copy2(src, dst)
|
||||
else:
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
|
||||
return db_dir
|
||||
|
||||
def get_user_db_path(user_id: str) -> str:
|
||||
"""Get the database path for a specific user."""
|
||||
# Sanitize user_id to be safe for filesystem
|
||||
safe_user_id = "".join(c for c in user_id if c.isalnum() or c in ('-', '_'))
|
||||
safe_user_id = _sanitize_user_id(user_id)
|
||||
user_workspace = os.path.join(WORKSPACE_DIR, f"workspace_{safe_user_id}")
|
||||
db_dir = ensure_user_workspace_db_directory(user_id)
|
||||
|
||||
# Check for legacy naming convention first (to support existing data)
|
||||
# Some older workspaces might have 'alwrity.db' instead of 'alwrity_{user_id}.db'
|
||||
legacy_db_path = os.path.join(user_workspace, 'db', 'alwrity.db')
|
||||
specific_db_path = os.path.join(user_workspace, 'db', f'alwrity_{safe_user_id}.db')
|
||||
legacy_db_path = os.path.join(db_dir, 'alwrity.db')
|
||||
specific_db_path = os.path.join(db_dir, f'alwrity_{safe_user_id}.db')
|
||||
|
||||
# Backward compatibility when filesystem migration couldn't run yet.
|
||||
legacy_dir_path = os.path.join(user_workspace, 'database', f'alwrity_{safe_user_id}.db')
|
||||
legacy_dir_default = os.path.join(user_workspace, 'database', 'alwrity.db')
|
||||
|
||||
# If the specific one exists, use it (preferred)
|
||||
if os.path.exists(specific_db_path):
|
||||
@@ -71,6 +112,12 @@ def get_user_db_path(user_id: str) -> str:
|
||||
# If legacy exists and specific doesn't, use legacy
|
||||
if os.path.exists(legacy_db_path):
|
||||
return legacy_db_path
|
||||
|
||||
if os.path.exists(legacy_dir_path):
|
||||
return legacy_dir_path
|
||||
|
||||
if os.path.exists(legacy_dir_default):
|
||||
return legacy_dir_default
|
||||
|
||||
# Default to specific for new databases
|
||||
return specific_db_path
|
||||
|
||||
Reference in New Issue
Block a user