v2.8.0
🚀 PDOdb v2.8.0 Release
Release Date: November 1, 2025
Overview
PDOdb v2.8.0 introduces major new features: ActiveRecord Pattern, Query Performance Profiling, Materialized CTEs, and PSR-14 Event Dispatcher Integration. Also includes improvements to exception handling, memory management, and code quality.
🎯 Major Features
✨ ActiveRecord Pattern (Optional ORM)
Lightweight ORM for object-based database operations:
- Magic attribute access -
$user->name,$user->email - Automatic CRUD -
save(),delete(),refresh() - Dirty tracking - Automatically tracks changed attributes
- Declarative validation - Rules-based validation with extensible validators
- Lifecycle events - PSR-14 events for save, insert, update, delete
- ActiveQuery builder - Full QueryBuilder API through
find()method
use tommyknocker\pdodb\orm\Model;
class User extends Model
{
public static function tableName(): string
{
return 'users';
}
public static function rules(): array
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
}
$user = new User();
$user->name = 'Alice';
$user->email = 'alice@example.com';
$user->save();📚 Documentation: documentation/05-advanced-features/active-record.md
📖 Examples: examples/23-active-record/
📊 Query Performance Profiling
Built-in profiler for performance analysis:
- Automatic tracking of all query executions
- Execution time measurement (total, average, min, max)
- Memory usage tracking per query
- Slow query detection with configurable threshold
- Query grouping by SQL structure
- PSR-3 logger integration
$db->enableProfiling(0.5); // Threshold: 0.5 seconds
// Execute queries (automatically tracked)
$users = $db->find()->from('users')->get();
// Get statistics
$stats = $db->getProfilerStats(true);
echo "Avg time: " . round($stats['avg_time'] * 1000, 2) . " ms\n";
// Get slowest queries
$slowest = $db->getSlowestQueries(10);📚 Documentation: documentation/05-advanced-features/query-profiling.md
📖 Examples: examples/21-query-profiling/
⚡ Materialized CTE Support
Performance optimization for expensive CTE queries:
- PostgreSQL: Uses
MATERIALIZEDkeyword - MySQL: Uses optimizer hints
- Automatically caches expensive CTE computations
$results = $db->find()
->withMaterialized('customer_stats', function ($q) {
$q->from('orders')
->select([
'customer_id',
'order_count' => Db::count('*'),
'total_spent' => Db::sum('amount'),
])
->groupBy('customer_id');
})
->from('customers')
->join('customer_stats', 'customers.id = customer_stats.customer_id')
->where('customer_stats.total_spent', 1000, '>')
->get();📚 Documentation: documentation/03-query-builder/cte.md
📖 Examples: examples/17-cte/03-materialized-cte.php
🎪 PSR-14 Event Dispatcher Integration
Event-driven architecture for monitoring, auditing, and middleware:
ConnectionOpenedEvent- When connection is openedQueryExecutedEvent- After successful query executionQueryErrorEvent- When query error occursTransactionStartedEvent,TransactionCommittedEvent,TransactionRolledBackEvent
use tommyknocker\pdodb\events\QueryExecutedEvent;
$dispatcher->addListener(QueryExecutedEvent::class, function (QueryExecutedEvent $event) {
echo sprintf(
"Query: %s (%.2f ms, %d rows)\n",
substr($event->getSql(), 0, 50),
$event->getExecutionTime(),
$event->getRowsAffected()
);
});📖 Examples: examples/19-events/
🔧 Improvements
Exception Handling
- 113 new tests for exception handling (ExceptionTests, ErrorDetectionStrategyTests, ConstraintParserTests, ErrorCodeRegistryTests)
- Improved
ConstraintParserwith better pattern matching - Enhanced constraint name extraction from error messages
- Better handling of
FOREIGN KEYandschema.tableformats
Memory Management
- Fixed memory leaks by properly closing PDOStatement cursors
- All fetch methods automatically close cursors
- Exception-safe cleanup using
try/finallyblocks - Production-tested with 50,000+ queries without memory accumulation
Code Quality
- Infection mutation testing integrated for code quality assurance
- SHA-256 hashing replaces all MD5 usage for better security
- Simplified external reference detection (KISS/YAGNI refactoring)
- Query compilation cache improvements
- Zero skipped tests policy - all tests actively run
Bug Fixes
- SQLite cache parameter validation (prevents invalid DSN parameters)
- SQL identifier quoting in FileLoader for different dialects
- LATERAL JOIN improvements with better external reference detection
- Markdown EOF formatting consistency
📈 Statistics
- Tests: 991 tests, 3951 assertions (+417 tests, +1425 assertions from 2.7.1)
- Examples: 147/147 passing (49 files × 3 dialects each)
- PHPStan: Level 8, zero errors
- Backward Compatibility: 100% maintained
🔗 Links
- Full Changelog: CHANGELOG.md
- Documentation: documentation/
- Examples: examples/
- Comparison: v2.7.1...v2.8.0
⬇️ Installation
composer require tommyknocker/pdo-database-class:^2.8.0🙏 Thank You
Special thanks to all contributors and users who helped make this release possible!
Full Changelog: v2.7.1...v2.8.0