# Database Module Migration Analysis Complete analysis of Database module exception migration requirements. ## Module Statistics - **Total PHP Files**: 292 - **Total Exceptions**: 111 exceptions to analyze - RuntimeException: 24 instances - InvalidArgumentException: 79 instances - DatabaseException: 8 instances (already using framework exception) - PDOException: 0 (caught and re-thrown) ## Exception Categories ### Category 1: PDO/Connection Errors (HIGH PRIORITY) **Files**: PdoConnection.php, ConnectionPool.php, DatabaseFactory.php **Count**: 8 existing + need SQLSTATE integration **Pattern**: Catch PDOException → Re-throw as specific exception **Examples**: ```php // PdoConnection.php:31 throw DatabaseException::simple("Failed to execute query: {$e->getMessage()}", $e); // ConnectionPool.php:72 throw DatabaseException::create(...) ``` **Migration Strategy**: - Implement SQLSTATE integration FIRST - Create QueryExecutionException, ConnectionFailedException, etc. - Extract SQLSTATE from PDOException - Map to specific DatabaseErrorCode ### Category 2: Unsupported Driver/Feature (MEDIUM PRIORITY) **Count**: 14 instances **Pattern**: `throw new \RuntimeException("Unsupported database driver: {$driver}")` **Files**: - QueryHistoryLogger.php:259 - Schema.php:107, 126, 143, 217 - SchemaBuilderFactory.php:43 - DatabasePlatformInitializer.php:28, 29 - DatabaseOptimizeCommand.php:196 - MigrationDatabaseManager.php:113 - StoredProcedureDefinition.php:213 **Migration Target**: `UnsupportedDriverException` or `FeatureNotSupportedException` **ErrorCode**: `DatabaseErrorCode::UNSUPPORTED_DRIVER` (new) **Examples**: ```php // Before default => throw new \RuntimeException("Unsupported database driver: {$driver}") // After default => throw UnsupportedDriverException::forDriver($driver) ``` ### Category 3: Invalid Schema/Compiler Arguments (MEDIUM PRIORITY) **Count**: 35 instances (mostly InvalidArgumentException) **Pattern**: Schema compiler validation, column type validation, index validation **Files**: - PostgreSQLSchemaCompiler.php: 7 instances - MySQLSchemaCompiler.php: 7 instances - SQLiteSchemaCompiler.php: 6 instances - Index/AdvancedIndexDefinition.php: 8 instances - Index/AdvancedIndexType.php: 4 instances **Decision**: **KEEP as InvalidArgumentException** - These are configuration/schema definition errors (developer errors) - Not runtime business logic exceptions - Similar to constructor validation **Examples to KEEP**: ```php // KEEP - Schema definition validation throw new \InvalidArgumentException("Unknown column type: {$column->type}") throw new \InvalidArgumentException("FULLTEXT index not supported by {$driver}") throw new \InvalidArgumentException('Fill factor must be between 10 and 100') ``` ### Category 4: Missing Required Configuration (MEDIUM PRIORITY) **Count**: 6 instances **Pattern**: Missing required data for operation **Files**: - SelectQueryBuilder.php:422, 497, 531 - SchemaBuilder.php:229 - StoredProcedureDefinition.php:164, 188, 217 **Migration Target**: `InvalidQueryStateException` or `MissingRequirementException` **ErrorCode**: `DatabaseErrorCode::INVALID_STATE` or `MISSING_REQUIREMENT` **Examples**: ```php // SelectQueryBuilder.php:422 throw new \RuntimeException('FROM clause is required'); // After throw InvalidQueryStateException::missingFromClause(); // SchemaBuilder.php:229 throw new \RuntimeException("Cannot create table '{$this->tableName}' without columns"); // After throw InvalidSchemaException::tableWithoutColumns($this->tableName); ``` ### Category 5: Missing Dependencies/Configuration (LOW PRIORITY) **Count**: 5 instances **Pattern**: Logger not configured, entity manager missing, etc. **Files**: - DatabaseManager.php:111 - ProfilingConnection.php:302 - LazyLoader.php:323, 332 **Migration Target**: `MissingDependencyException` **ErrorCode**: `DatabaseErrorCode::DEPENDENCY_MISSING` (new) **Examples**: ```php // DatabaseManager.php:111 throw new \RuntimeException('Clock is required for database profiling'); // After throw MissingDependencyException::forComponent('Clock', 'Database profiling'); ``` ### Category 6: Repository/Query Errors (LOW PRIORITY) **Count**: 12 instances (InvalidArgumentException) **Pattern**: Validation in repository methods, pagination, profiling **Files**: - PaginatedResult.php: 4 instances - Restrictions.php: 2 instances - QueryProfiler.php: 2 instances - SlowQueryDetector.php: 1 instance - Various export/format errors **Decision**: **MIXED - Analyze case by case** **Keep (Constructor Validation)**: ```php // PaginatedResult.php:20 - KEEP throw new \InvalidArgumentException('Current page must be at least 1'); ``` **Migrate (Business Logic)**: ```php // Restrictions.php:159 - MIGRATE throw new \InvalidArgumentException('At least one criterion is required'); // Should be: InvalidCriteriaException::empty() ``` ### Category 7: Profiling/Monitoring Errors (LOW PRIORITY) **Count**: 8 instances **Pattern**: Configuration errors in profiling/monitoring **Files**: - ProfilingDashboard.php: 4 instances - QueryProfiler.php, QueryLogger.php, SlowQueryDetector.php **Decision**: **KEEP most, MIGRATE connection-not-found** **Migrate**: ```php // ProfilingDashboard.php:91 throw new \InvalidArgumentException("Connection '$connectionName' not registered"); // Should be: ConnectionNotFoundException::byName($connectionName) ``` ## Recommended Exception Classes ### 1. SQLSTATE-Aware Exceptions (HIGH PRIORITY) ```php QueryExecutionException // General query failures with SQLSTATE ConnectionFailedException // Connection errors (SQLSTATE 08xxx) ConstraintViolationException // Constraint violations (SQLSTATE 23xxx) DeadlockException // Deadlocks (SQLSTATE 40001) TransactionException // Transaction errors ``` ### 2. Configuration/Schema Exceptions (MEDIUM PRIORITY) ```php UnsupportedDriverException // Unsupported database driver UnsupportedFeatureException // Feature not supported by driver InvalidQueryStateException // Missing FROM clause, etc. InvalidSchemaException // Schema definition errors MigrationException // Migration-specific errors ``` ### 3. Dependency Exceptions (LOW PRIORITY) ```php MissingDependencyException // Missing required components ConnectionNotFoundException // Connection not found in pool/registry ``` ### 4. Query Builder Exceptions (LOW PRIORITY) ```php InvalidCriteriaException // Criteria/Restrictions errors ``` ## Migration Phases ### Phase 1: SQLSTATE Foundation (CRITICAL PATH) **Time**: 2-3 hours **Priority**: HIGH 1. Create `SqlState` value object 2. Create `SqlStateErrorMapper` service 3. Extend `DatabaseErrorCode` enum with all codes 4. Write comprehensive tests **Deliverables**: - `/src/Framework/Database/ValueObjects/SqlState.php` - `/src/Framework/Database/Services/SqlStateErrorMapper.php` - `/src/Framework/Exception/Core/DatabaseErrorCode.php` (extended) - `/tests/Unit/Framework/Database/SqlStateTest.php` ### Phase 2: SQLSTATE Exception Classes (CRITICAL PATH) **Time**: 3-4 hours **Priority**: HIGH 1. Create `QueryExecutionException` with SQLSTATE 2. Create `ConnectionFailedException` with SQLSTATE 3. Create `ConstraintViolationException` with SQLSTATE 4. Create `DeadlockException` with SQLSTATE 5. Create `TransactionException` **Deliverables**: - 5 exception classes in `/src/Framework/Database/Exception/` - Factory methods with rich context - Integration tests with mock PDOExceptions ### Phase 3: Core Connection Migration (CRITICAL PATH) **Time**: 2-3 hours **Priority**: HIGH 1. Update `PdoConnection` with `handlePdoException()` 2. Update `ConnectionPool` exception handling 3. Update `DatabaseFactory` connection errors 4. Integration tests with real database **Files**: - `PdoConnection.php` (5 exceptions) - `ConnectionPool.php` (3 exceptions) - `DatabaseFactory.php` ### Phase 4: Configuration Exceptions (MEDIUM PRIORITY) **Time**: 2-3 hours **Priority**: MEDIUM 1. Create `UnsupportedDriverException` 2. Create `UnsupportedFeatureException` 3. Create `InvalidQueryStateException` 4. Create `InvalidSchemaException` 5. Migrate 14 unsupported driver errors 6. Migrate 6 missing requirement errors **Files**: - Schema.php, SchemaBuilderFactory.php, etc. (14 files) - SelectQueryBuilder.php, SchemaBuilder.php, etc. (6 files) ### Phase 5: Dependency Exceptions (LOW PRIORITY) **Time**: 1-2 hours **Priority**: LOW 1. Create `MissingDependencyException` 2. Create `ConnectionNotFoundException` 3. Migrate 5 missing dependency errors 4. Migrate 4 connection-not-found errors **Files**: - DatabaseManager.php, ProfilingConnection.php, LazyLoader.php - ProfilingDashboard.php ### Phase 6: Query Builder Exceptions (LOW PRIORITY) **Time**: 1 hour **Priority**: LOW 1. Create `InvalidCriteriaException` 2. Migrate Restrictions.php errors (2 instances) ## Total Effort Estimate **High Priority (Phases 1-3)**: 7-10 hours - SQLSTATE Foundation: 2-3h - SQLSTATE Exceptions: 3-4h - Core Connection Migration: 2-3h **Medium Priority (Phase 4)**: 2-3 hours **Low Priority (Phases 5-6)**: 2-3 hours **Total**: 11-16 hours ## Success Criteria ### Must Have (Phase 1-3) - [x] SQLSTATE integration complete - [x] All PDOException catches handled - [x] Connection errors user-friendly - [x] Constraint violations descriptive - [x] Deadlocks with automatic retry - [x] Integration tests passing ### Should Have (Phase 4) - [ ] Unsupported driver errors clear - [ ] Query state errors descriptive - [ ] Schema errors actionable ### Nice to Have (Phase 5-6) - [ ] All dependency errors migrated - [ ] Query builder exceptions complete ## Risk Assessment **High Risk**: - SQLSTATE mapping completeness - Mitigate: Comprehensive test coverage - Breaking changes to existing code - Mitigate: Maintain backward compatibility via DatabaseException::simple() - Performance impact - Mitigate: Benchmark critical paths **Medium Risk**: - Test database setup complexity - Mitigate: Use SQLite for tests - Migration effort underestimation - Mitigate: Phased approach **Low Risk**: - Documentation completeness - Mitigate: Update docs incrementally ## Decision Matrix ### What to Migrate **YES - Migrate to specific exceptions**: - ✅ PDOException catches → SQLSTATE-aware exceptions - ✅ Unsupported driver errors → UnsupportedDriverException - ✅ Missing FROM clause → InvalidQueryStateException - ✅ Connection not found → ConnectionNotFoundException - ✅ Missing dependencies (Clock, etc.) → MissingDependencyException - ✅ Empty criteria → InvalidCriteriaException **NO - Keep as InvalidArgumentException**: - ❌ Constructor parameter validation - ❌ Schema compiler column type validation - ❌ Index type validation - ❌ Fill factor range validation - ❌ Page number validation (PaginatedResult constructor) - ❌ Export format validation (in __construct or similar) **MAYBE - Analyze context**: - ⚠️ Profile ID not found → Consider ProfileNotFoundException - ⚠️ Slow query threshold validation → Keep as InvalidArgumentException ## Files Requiring Changes ### Critical Path (Phase 1-3) - 8 files ``` src/Framework/Database/PdoConnection.php src/Framework/Database/ConnectionPool.php src/Framework/Database/DatabaseFactory.php src/Framework/Database/Middleware/RetryMiddleware.php src/Framework/Database/ValueObjects/SqlState.php (NEW) src/Framework/Database/Services/SqlStateErrorMapper.php (NEW) src/Framework/Database/Exception/QueryExecutionException.php (NEW) src/Framework/Database/Exception/ConnectionFailedException.php (NEW) src/Framework/Database/Exception/ConstraintViolationException.php (NEW) src/Framework/Database/Exception/DeadlockException.php (NEW) src/Framework/Database/Exception/TransactionException.php (NEW) src/Framework/Exception/Core/DatabaseErrorCode.php (EXTEND) ``` ### Medium Priority (Phase 4) - 20 files ``` src/Framework/Database/Schema/Schema.php src/Framework/Database/Platform/SchemaBuilderFactory.php src/Framework/Database/Platform/DatabasePlatformInitializer.php src/Framework/Database/QueryBuilder/SelectQueryBuilder.php src/Framework/Database/Schema/SchemaBuilder.php src/Framework/Database/StoredProcedure/StoredProcedureDefinition.php ... (14 more schema/driver files) ``` ### Low Priority (Phase 5-6) - 10 files ``` src/Framework/Database/DatabaseManager.php src/Framework/Database/Profiling/ProfilingConnection.php src/Framework/Database/LazyLoader.php src/Framework/Database/Profiling/ProfilingDashboard.php src/Framework/Database/Criteria/Restrictions.php ... (5 more profiling/query files) ``` ## Next Steps 1. **Start with Phase 1**: SQLSTATE Foundation 2. **Validate design** with tests before Phase 2 3. **Incremental migration**: Complete one phase before next 4. **Test coverage**: ≥80% for new exception classes 5. **Documentation**: Update database-patterns.md incrementally ## Questions to Resolve 1. Should `ProfileNotFoundException` be created or keep as InvalidArgumentException? 2. Should migration-specific errors get their own exception class or reuse InvalidSchemaException? 3. Should export format errors be migrated or kept as InvalidArgumentException? **Recommendation**: Start simple, migrate obvious cases first, defer edge cases to later phases.