Files
Chris Coutinho 3fa376905c feat: add Alembic database migration system
Implements Alembic for managing token storage database schema versions.
Migrations run automatically on startup with full backward compatibility.

**Changes:**
- Add Alembic dependency (1.14.0+) and SQLAlchemy (auto-installed)
- Create migration infrastructure in alembic/ directory
- Add initial migration (001) capturing current schema
- Modify RefreshTokenStorage.initialize() to run migrations via anyio
- Add CLI commands: db upgrade, current, history, downgrade, migrate
- Add comprehensive migration documentation

**Backward Compatibility:**
- Pre-Alembic databases automatically stamped with revision 001
- No schema changes for existing databases
- Automatic upgrade on first startup after update

**Migration Strategy:**
Three scenarios handled:
1. New database → Run migrations from scratch
2. Pre-Alembic database → Stamp with 001 (no changes)
3. Alembic-managed → Upgrade to latest

**Architecture:**
- Uses anyio.to_thread.run_sync() for structured concurrency
- Alembic env.py runs with anyio.run() in worker thread
- SQLite-friendly migration patterns documented
- No ThreadPoolExecutor needed (anyio handles it)

**CLI Usage:**
```bash
nextcloud-mcp-server db upgrade    # Upgrade to latest
nextcloud-mcp-server db current    # Show version
nextcloud-mcp-server db history    # View changelog
nextcloud-mcp-server db downgrade  # Rollback (with confirmation)
nextcloud-mcp-server db migrate "description"  # Create migration
```

**Testing:**
- All 13 webhook storage tests pass
- New/pre-Alembic database scenarios validated
- anyio integration tested

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 00:02:09 +01:00

72 lines
2.2 KiB
Plaintext

Database Migrations for nextcloud-mcp-server
============================================
This directory contains Alembic database migrations for the token storage database.
Structure
---------
- env.py: Alembic environment configuration
- script.py.mako: Template for generating new migration files
- versions/: Directory containing migration scripts
Usage
-----
Migrations are managed via the CLI:
# Upgrade database to latest version
uv run nextcloud-mcp-server db upgrade
# Show current database version
uv run nextcloud-mcp-server db current
# Show migration history
uv run nextcloud-mcp-server db history
# Create a new migration (developers only)
uv run nextcloud-mcp-server db migrate "description of changes"
# Downgrade database by one version (emergency use only)
uv run nextcloud-mcp-server db downgrade
Direct Alembic Usage
--------------------
You can also use Alembic commands directly:
# Specify database URL via -x flag
uv run alembic -x database_url=sqlite+aiosqlite:////path/to/tokens.db upgrade head
# Or set in alembic.ini and run
uv run alembic upgrade head
uv run alembic current
uv run alembic history
Writing Migrations
------------------
Since we don't use SQLAlchemy models, migrations are written with raw SQL:
def upgrade() -> None:
op.execute("""
ALTER TABLE refresh_tokens
ADD COLUMN new_field TEXT
""")
def downgrade() -> None:
# SQLite doesn't support DROP COLUMN, use table recreation
op.execute("""
CREATE TABLE refresh_tokens_new AS
SELECT user_id, encrypted_token, ... FROM refresh_tokens
""")
op.execute("DROP TABLE refresh_tokens")
op.execute("ALTER TABLE refresh_tokens_new RENAME TO refresh_tokens")
Migration File Naming
---------------------
Format: YYYYMMDD_HHMM_<revision>_<slug>.py
Example: 20251217_2200_001_initial_schema.py
Notes
-----
- Migrations run automatically when RefreshTokenStorage.initialize() is called
- Existing databases are automatically stamped with the initial version
- SQLite has limited ALTER TABLE support - complex changes require table recreation