Skip to content

Commit 1aef66f

Browse files
committed
chore: update CHANGELOG.md for v2.5.1 release
1 parent 11fd698 commit 1aef66f

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

CHANGELOG.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
---
1111

12+
## [2.5.1] - 2025-10-22
13+
14+
### Added
15+
- **Db::inc() and Db::dec() support in onDuplicate()**: Now you can use convenient helpers for UPSERT increments
16+
- Works across all dialects: MySQL, PostgreSQL, SQLite
17+
- Example: `->onDuplicate(['counter' => Db::inc(5)])`
18+
- Automatically generates dialect-specific SQL (e.g., `counter = counter + 5`)
19+
- **CI testing for examples**: All 21 examples now tested in GitHub Actions
20+
- SQLite: 21/21 examples verified
21+
- MySQL: 20/20 examples verified (if database available)
22+
- PostgreSQL: 20/20 examples verified (if database available)
23+
- **New tests** for UPSERT functionality:
24+
- `testUpsertWithRawIncrement()` - tests `Db::raw('age + 5')` in onDuplicate
25+
- `testUpsertWithIncHelper()` - tests `Db::inc(5)` in onDuplicate
26+
- `testGroupByWithQualifiedNames()` - verifies qualified column names in GROUP BY
27+
28+
### Changed
29+
- **All examples migrated to QueryBuilder API**:
30+
- Replaced 15+ `rawQuery()` calls with fluent QueryBuilder methods
31+
- `rawQuery()` now used ONLY for DDL (CREATE/ALTER/DROP TABLE)
32+
- Examples demonstrate best practices with `Db::` helpers
33+
- **Enhanced buildUpsertClause() signature** (backwards compatible):
34+
- Added optional `$tableName` parameter for PostgreSQL ambiguous column resolution
35+
- Enables proper `Db::inc()` and `Db::raw()` support in UPSERT operations
36+
- **Improved test-examples.sh script**:
37+
- Fixed PostgreSQL port detection in connection checks
38+
- Now correctly detects all 3 database dialects when available
39+
- **JSON column handling**: Examples automatically use JSONB for PostgreSQL, TEXT for MySQL/SQLite
40+
41+
### Fixed
42+
- **CRITICAL: groupBy() and orderBy() with qualified column names** (`u.id`, `t.name`):
43+
- **Bug**: Qualified names quoted as single identifier `` `u.id` `` instead of `` `u`.`id` ``
44+
- **Impact**: Broke on MySQL/PostgreSQL with "Unknown column 'u.id'" error
45+
- **Fix**: Changed to use `quoteQualifiedIdentifier()` instead of `quoteIdentifier()`
46+
- **Tests**: Added `testGroupByWithQualifiedNames()` for all 3 dialects
47+
- **CRITICAL: Db::inc()/Db::dec() ignored in onDuplicate()**:
48+
- **Bug**: Dialects didn't handle `['__op' => 'inc']` array format in UPSERT
49+
- **Impact**: UPSERT replaced value instead of incrementing
50+
- **Fix**: Added `is_array($expr) && isset($expr['__op'])` handling in all dialects
51+
- **PostgreSQL UPSERT "ambiguous column" errors**:
52+
- **Bug**: `Db::raw('age + 5')` in onDuplicate caused "column reference ambiguous"
53+
- **Impact**: PostgreSQL couldn't distinguish old vs new column values
54+
- **Fix**: Auto-qualify column references with table name (`user_stats."age" + 5`)
55+
- **PostgreSQL lastInsertId() exception for non-SERIAL tables**:
56+
- **Bug**: Crash when inserting into tables without auto-increment
57+
- **Fix**: Added try-catch in `executeInsert()` to gracefully handle missing sequence
58+
- **String literal quoting in SQL expressions**:
59+
- Fixed PostgreSQL compatibility (uses `'string'` not `"string"`)
60+
- Fixed CASE WHEN conditions to use single quotes for string literals
61+
- Examples now properly escape string values in Db::raw() expressions
62+
- **Examples multi-dialect compatibility**:
63+
- JSON columns: Use JSONB for PostgreSQL, TEXT for MySQL/SQLite
64+
- String concatenation: Dialect-aware (`||` vs `CONCAT()`)
65+
- Date/time functions: Dialect-specific interval syntax
66+
- All 21 examples verified on all 3 dialects
67+
68+
### Technical Details
69+
- **All tests passing**: 343 tests, 1544 assertions (up from 334 tests)
70+
- Added 9 new tests across MySQL, PostgreSQL, SQLite
71+
- Zero failures, zero errors, zero warnings
72+
- **All examples passing**: 61/61 total runs (21 examples × ~3 dialects each)
73+
- SQLite: 21/21 ✅
74+
- MySQL: 20/20 ✅ (01-connection.php uses SQLite only)
75+
- PostgreSQL: 20/20 ✅
76+
- **PHPStan Level 8**: Zero errors across entire codebase
77+
- **Full backwards compatibility**: Optional parameter with default value
78+
79+
---
80+
1281
## [2.5.0] - 2025-10-19
1382

1483
### Added
@@ -308,7 +377,8 @@ Initial tagged release with basic PDO database abstraction functionality.
308377

309378
---
310379

311-
[Unreleased]: https://github.com/tommyknocker/pdo-database-class/compare/v2.5.0...HEAD
380+
[Unreleased]: https://github.com/tommyknocker/pdo-database-class/compare/v2.5.1...HEAD
381+
[2.5.1]: https://github.com/tommyknocker/pdo-database-class/compare/v2.5.0...v2.5.1
312382
[2.5.0]: https://github.com/tommyknocker/pdo-database-class/compare/v2.4.3...v2.5.0
313383
[2.4.3]: https://github.com/tommyknocker/pdo-database-class/compare/v2.4.2...v2.4.3
314384
[2.4.2]: https://github.com/tommyknocker/pdo-database-class/compare/v2.4.1...v2.4.2

0 commit comments

Comments
 (0)