2.1.2
2.1.2 release
Security
SQL Identifier Validation & Escaping — Introduced a new IdentifierValidator class that validates and escapes all SQL identifiers (table names, column names, aliases) with backtick wrapping. Enforces strict pattern matching, max length (64 chars), SQL keyword detection, and injection pattern rejection across all query builder methods.
Identifier validation applied across all statements — SELECT, INSERT, ALTER, WHERE, JOIN, ORDER BY, GROUP BY, COUNT, and sub-query methods now validate identifiers through IdentifierValidator.
New Features
Multi-column orderBy with associative array — orderBy now accepts an associative array for sorting by multiple columns with individual sort directions:
->orderBy(['name' => 'ASC', 'created_at' => 'DESC'])
Table alias support in from — The from method now parses table alias syntax (e.g., ->from('users u')).
validateTableNameWithAlias — New validation method for table names with aliases used in JOIN operations.
Wildcard * support — Column validation now correctly passes through * for SELECT * queries.
Bug Fixes
PDO connection singleton — Cached the PDO instance in Connect::pdo() to prevent "Too many connections" errors when running multiple queries.
Exception trace OOM fix — Changed print_r($exception->getTrace()) to $exception->getTraceAsString() in Utilities::throughException() to prevent out-of-memory crashes.
Test suite fixes — Fixed missing ->execute() calls in AlterTest, corrected foreign key drop order in CreateTest, and updated exception namespaces.
Code Quality
PSR-12 method naming — Refactored Insert private methods from snake_case to camelCase (get_table_name → getTableName, etc.).
Distribution cleanup — Added .gitattributes to exclude dev files (tests, config files) from Composer archives.
Expanded test coverage — 27 unit tests for IdentifierValidator covering valid/invalid identifiers, SQL injection patterns, aliases, max length, and edge cases. Full suite: 170+ tests passing.
Documentation
Added donation page to documentation site.