Releases: webrium/foxdb
FoxDB 4.0.2
What's Changed
- V4/core foundation by @benkhalife in #46
- fix(ci): resolve PHP 8.1 and PostgreSQL compatibility issues by @benkhalife in #48
- fix(pgsql): embed RawExpression in UPDATE without placeholder by @benkhalife in #50
- model json encodemodel returns and ide loses type after where first by @benkhalife in #52
- Fix/where column name collision by @benkhalife in #55
Full Changelog: 3.1.2...4.0.2
FoxDB 4.0.1
🦊 FoxDB v4 — A Full Database Toolkit
FoxDB started as a lightweight query builder. Version 4 is something bigger: a complete database toolkit for PHP 8.1+ with an ORM, schema management, migrations, and a richer query pipeline — all with zero external dependencies.
✨ What's New
Eloquent-style ORM
Define your database tables as PHP classes. FoxDB handles the rest — mass assignment protection, automatic timestamps, dirty tracking (only changed columns are written on save), and full JSON serialization with hidden fields and casts applied automatically.
Attribute Casting
Declare $casts on your model and FoxDB converts raw database values to the correct PHP type on every read. Integers come back as int, JSON columns as array, booleans as bool, and datetime columns as DateTime objects — no manual conversion needed.
Relations
Define relationships between models with hasOne, hasMany, belongsTo, belongsToMany, and hasManyThrough. Lazy loading works out of the box, and eager loading (with()) lets you eliminate N+1 queries with a single method call. Relations are included automatically when you call toArray().
Soft Deletes
Add use HasSoftDeletes to a model and delete operations set a deleted_at timestamp instead of removing the row. Soft-deleted rows are excluded from all queries by default, and can be restored at any time. withTrashed() and onlyTrashed() give you full control when you need it.
Local Scopes
Encapsulate reusable query conditions as methods on your model. A method named scopeActive becomes User::active() — fully chainable with other builder methods and other scopes.
Schema Builder
Create and modify tables using a fluent Blueprint API. Columns, indexes, foreign keys, unique constraints — all written in PHP, all generating the correct DDL for your driver.
Migrations
Version your schema changes with up() and down() methods. Run pending migrations, roll back the last batch, reset everything, or refresh the entire database in one call.
Collection
Query results are wrapped in a rich Collection class with map, filter, sort, chunk, pluck, groupBy, and aggregate methods. The collection is immutable — every transformation returns a new instance. It implements JsonSerializable, so json_encode($collection) just works.
Multi-driver Support
MySQL, PostgreSQL, and SQLite all work correctly with per-driver SQL generation. Identifier quoting, upsert syntax, boolean defaults, datetime types, and UPDATE semantics are all handled correctly for each database.
Query Log & Hooks
Log every query that runs, measure execution time, detect slow queries above a threshold, and attach beforeQuery / afterQuery callbacks for monitoring or external logging.
PHPUnit Test Suite
A new test suite with unit tests for SQL generation and model logic, and integration tests that run against all three supported drivers. CI runs the full suite on PHP 8.1, 8.2, and 8.3 across MySQL 8.0/8.4, PostgreSQL 15/16, and SQLite on every pull request.
IDE Autocompletion
Full @method PHPDoc annotations on the base Model class. Every query method — where, orderBy, limit, paginate, and all the rest — appears in your IDE's autocomplete when you call User:: or Post::.
🐛 Bug Fixes
-
Model::__callStatic()crashed when a Builder method returned a model instance. The return type was declared asBuilder, but terminal Builder methods likefirst(),find(), andvalue()can return model instances, scalars, or null. PHP 8's strict return type enforcement caused aTypeErrorat runtime. -
isset($model->relation)always returned false after eager loading.__isset()only checked$attributes, so loaded relations were invisible toisset()checks. It now checks both$attributesand$relations. -
HasSoftDeletesnot detected when inherited from a parent model.ReflectionClass::getTraits()only returns traits declared directly on a class. A subclass inheritingHasSoftDeletesfrom a parent was not recognized, so theWHERE deleted_at IS NULLscope was silently skipped. Fixed by walking the full class hierarchy. -
PostgresGrammar::compileUpdate()caused a binding count mismatch forincrement()anddecrement(). The method always emittedcol = ?for every column, even forRawExpressionvalues that should be embedded directly. PostgreSQL received a?placeholder with no bound value and rejected the query. -
Connection::handleException()declared): falseas a standalone return type, which is only valid from PHP 8.2. Caused a fatal error on PHP 8.1 before any tests could run. -
Integration test schemas used
DATETIMEandBOOLEAN DEFAULT 1, both invalid in PostgreSQL. PostgreSQL requiresTIMESTAMPandTRUE/FALSErespectively. Cross-driver DDL helpers were added toIntegrationTestCaseto handle these differences cleanly.
💬 Notes
FoxDB v4 is a major version with a new ORM layer built on top of the query builder. The query builder API from v3 is unchanged — existing code continues to work without modification. The new ORM features are purely additive.
Full Changelog: 3.1.2...4.0.1
FoxDB 4.0.0
🦊 FoxDB v4 — A Full Database Toolkit
FoxDB started as a lightweight query builder. Version 4 is something bigger: a complete database toolkit for PHP 8.1+ with an ORM, schema management, migrations, and a richer query pipeline — all with zero external dependencies.
✨ What's New
Eloquent-style ORM
Define your database tables as PHP classes. FoxDB handles the rest — mass assignment protection, automatic timestamps, dirty tracking (only changed columns are written on save), and full JSON serialization with hidden fields and casts applied automatically.
Attribute Casting
Declare $casts on your model and FoxDB converts raw database values to the correct PHP type on every read. Integers come back as int, JSON columns as array, booleans as bool, and datetime columns as DateTime objects — no manual conversion needed.
Relations
Define relationships between models with hasOne, hasMany, belongsTo, belongsToMany, and hasManyThrough. Lazy loading works out of the box, and eager loading (with()) lets you eliminate N+1 queries with a single method call. Relations are included automatically when you call toArray().
Soft Deletes
Add use HasSoftDeletes to a model and delete operations set a deleted_at timestamp instead of removing the row. Soft-deleted rows are excluded from all queries by default, and can be restored at any time. withTrashed() and onlyTrashed() give you full control when you need it.
Local Scopes
Encapsulate reusable query conditions as methods on your model. A method named scopeActive becomes User::active() — fully chainable with other builder methods and other scopes.
Schema Builder
Create and modify tables using a fluent Blueprint API. Columns, indexes, foreign keys, unique constraints — all written in PHP, all generating the correct DDL for your driver.
Migrations
Version your schema changes with up() and down() methods. Run pending migrations, roll back the last batch, reset everything, or refresh the entire database in one call.
Collection
Query results are wrapped in a rich Collection class with map, filter, sort, chunk, pluck, groupBy, and aggregate methods. The collection is immutable — every transformation returns a new instance. It implements JsonSerializable, so json_encode($collection) just works.
Multi-driver Support
MySQL, PostgreSQL, and SQLite all work correctly with per-driver SQL generation. Identifier quoting, upsert syntax, boolean defaults, datetime types, and UPDATE semantics are all handled correctly for each database.
Query Log & Hooks
Log every query that runs, measure execution time, detect slow queries above a threshold, and attach beforeQuery / afterQuery callbacks for monitoring or external logging.
PHPUnit Test Suite
A new test suite with unit tests for SQL generation and model logic, and integration tests that run against all three supported drivers. CI runs the full suite on PHP 8.1, 8.2, and 8.3 across MySQL 8.0/8.4, PostgreSQL 15/16, and SQLite on every pull request.
IDE Autocompletion
Full @method PHPDoc annotations on the base Model class. Every query method — where, orderBy, limit, paginate, and all the rest — appears in your IDE's autocomplete when you call User:: or Post::.
🐛 Bug Fixes
-
Model::__callStatic()crashed when a Builder method returned a model instance. The return type was declared asBuilder, but terminal Builder methods likefirst(),find(), andvalue()can return model instances, scalars, or null. PHP 8's strict return type enforcement caused aTypeErrorat runtime. -
isset($model->relation)always returned false after eager loading.__isset()only checked$attributes, so loaded relations were invisible toisset()checks. It now checks both$attributesand$relations. -
HasSoftDeletesnot detected when inherited from a parent model.ReflectionClass::getTraits()only returns traits declared directly on a class. A subclass inheritingHasSoftDeletesfrom a parent was not recognized, so theWHERE deleted_at IS NULLscope was silently skipped. Fixed by walking the full class hierarchy. -
PostgresGrammar::compileUpdate()caused a binding count mismatch forincrement()anddecrement(). The method always emittedcol = ?for every column, even forRawExpressionvalues that should be embedded directly. PostgreSQL received a?placeholder with no bound value and rejected the query. -
Connection::handleException()declared): falseas a standalone return type, which is only valid from PHP 8.2. Caused a fatal error on PHP 8.1 before any tests could run. -
Integration test schemas used
DATETIMEandBOOLEAN DEFAULT 1, both invalid in PostgreSQL. PostgreSQL requiresTIMESTAMPandTRUE/FALSErespectively. Cross-driver DDL helpers were added toIntegrationTestCaseto handle these differences cleanly.
💬 Notes
FoxDB v4 is a major version with a new ORM layer built on top of the query builder. The query builder API from v3 is unchanged — existing code continues to work without modification. The new ORM features are purely additive.
Full Changelog: 3.1.2...4.0.0
FoxDB 3.1.2
What's Changed
- feat: add static query() method to Model class by @benkhalife in #39
Full Changelog: 3.1.1...3.1.2
3.1.1
fix: Add explicit nullable type for $previous parameter in constructor
Full Changelog: 3.1.0...3.1.1
3.1.0
What's Changed
- Fix issue #29: whereIn methods now handle empty arrays gracefully by @mudassaralichouhan in #32
- Fix: Update queryMakerIn to handle empty array cases for NOT operatio… by @benkhalife in #35
- Fix #34: whereBetween methods now throw exceptions for invalid input by @mudassaralichouhan in #38
- Add robust error handling with custom exceptions and expand test cove… by @mudassaralichouhan in #37
Full Changelog: 3.0.4...3.1.0
3.0.4
3.0.3
Full Changelog: 3.0.2...3.0.3
3.0.2
What's Changed
- Fix pagination logic in paginate() method by @mudassaralichouhan in #28
New Contributors
- @mudassaralichouhan made their first contribution in #28
Full Changelog: 3.0.1...3.0.2