marwen-brini / bob-the-builder
A complete ORM and query builder for PHP with Laravel-like fluent syntax, models, relationships, and migrations
Fund package maintenance!
Marwen-Brini
Installs: 13
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/marwen-brini/bob-the-builder
Requires (Dev)
- laravel/pint: ^1.13
- mockery/mockery: ^1.6
- pestphp/pest: ^2.0|^3.0
- dev-main
- 3.0.0
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.7
- 2.0.0
- v1.0.0
- dev-feat/migration-system-blueprint-with-columns-type
- dev-fix/inconsitant-model-behavior
- dev-fix/global-scope-field-reference
- dev-feat/last-inserted-id-method
- dev-feat/model-level-global-scope
- dev-feat/add-forcefill
- dev-fix/double-prefix-in-builder-with-joins
- dev-feat/add-query-caching-for-repeated-exist-checks
- dev-fix/table-prefix-in-join-closures
- dev-fix/global-scope-in-relationships-inconsistency
- dev-fix/select-queries-dont-hydrate-model-attributes
- dev-fix/php-depracation-warning
- dev-fix/model-not-clearing-after-delete
- dev-fix/exists-bug
- dev-fix/deprecated-saignatures
- dev-fix/subquery-support
- dev-fix/aggregate-functions
- dev-fix/scope-chaining
- dev-fix/paremt-model-delete-method
- dev-fix/malformed_sql_on_chaining
- dev-fix/global_scopes
- dev-feature/relationships
This package is auto-updated.
Last update: 2025-12-01 00:17:07 UTC
README
A highly optimized, standalone PHP query builder with Laravel-like fluent syntax. Originally designed to enhance Quantum ORM's query building capabilities, Bob Query Builder is a fully independent package that can be used in ANY PHP project - from WordPress plugins to modern PHP frameworks, microservices, or standalone applications.
Why Bob Query Builder?
While initially created to modernize Quantum ORM's query building capabilities, Bob Query Builder was designed from the ground up as a universal PHP query builder that can enhance ANY PHP application:
- ✅ Framework Agnostic - Use it with Laravel, Symfony, WordPress, or vanilla PHP
- ✅ Zero Lock-in - No framework dependencies, just pure PHP and PDO
- ✅ Modern PHP - Built for PHP 8.1+ with full type safety
- ✅ Production Ready - 1773 tests, 100% passing, battle-tested
- ✅ High Performance - <10ms query building overhead, handles 50k+ rows efficiently
Features
- 🚀 Full ORM with ActiveRecord - Complete ORM layer with models and relationships (v2.0)
- 🔗 Laravel-like Relationships - HasOne, HasMany, BelongsTo, BelongsToMany with eager loading
- 🗄️ Database Migrations - Complete migration system with versioning and rollbacks (v3.0)
- 🏗️ Schema Builder - Fluent interface for creating and modifying database tables
- 🔍 Schema Inspector - Reverse engineer existing databases and generate migrations
- 🌐 WordPress Schema Support - Specialized helpers for WordPress/WooCommerce tables
- 💼 Laravel-like Fluent Interface - Familiar, expressive query builder syntax
- 🔧 Database Agnostic - Support for MySQL, PostgreSQL, SQLite via PDO
- 🎯 Zero Dependencies - Only requires PHP and PDO
- ⚡ High Performance - Query caching, prepared statements, 1M+ rows/second streaming
- 🧪 Fully Tested - 1773 tests with Pest, 100% code coverage
- 🔒 Secure - Automatic SQL injection prevention via parameter binding
- 📦 Modular - Easy integration with ANY PHP project, use as query builder or full ORM
- 🔄 Transaction Support - Including savepoints for nested transactions
- 📊 PSR-3 Logging - Built-in query logging with slow query detection
- 💾 Memory Efficient - Stream 50k+ rows with minimal memory usage
- 🎁 Collections - Powerful collection class for working with result sets
- 🎪 Event System - Hook into migration lifecycle with custom event listeners
Recent Updates (v3.0.0) 🎉
🗄️ Complete Migration System & Schema Builder
Bob v3.0 introduces a comprehensive database migration and schema management system:
- Schema Builder - Fluent interface for creating and modifying database tables across MySQL, PostgreSQL, and SQLite
- Migration System - Complete migration lifecycle management with versioning, rollbacks, and batch tracking
- WordPress Support - Specialized
WordPressBlueprintwith helpers for WordPress and WooCommerce schemas - Schema Inspector - Reverse engineer existing databases and generate migration files automatically
- Event System - Hook into migration lifecycle events for logging and custom workflows
- Migration Features:
- Dependency resolution between migrations
- Transaction support with automatic rollback on failure
- Lifecycle hooks (
before(),after()) - Pretend mode for safe testing
- Batch tracking and status reporting
See the Database Migrations & Schema Builder section for complete documentation.
Previous Updates (v2.2.2)
🎯 100% Code Coverage Achieved!
The test suite now has complete 100% code coverage across all components:
- ✅ 1773 tests passing with 4387 assertions
- ✅ Model class: Full coverage including edge cases for existing ID updates
- ✅ All test failures resolved: Fixed naming conflicts and relationship configurations
- ✅ Enhanced test reliability: Better handling of complex scenarios
🛠️ Test Suite Improvements
- Fixed class naming conflicts in Issue #13 debug tests
- Updated Issue #15 test expectations to reflect corrected behavior
- Improved BelongsToMany relationship tests for WordPress-style tables
- Added comprehensive tests for models with existing database IDs
Previous Updates (v2.2.1)
🛠️ Bug Fixes
Global Scope Field References in WHERE Clauses
Fixed an important issue with global scopes and field references:
- ✅ Global scopes now apply in toSql() - SQL generation now includes global scope modifications
- ✅ Prevents duplicate scope application - Added tracking to ensure scopes apply only once
- ✅ No side effects - Clone builder in toSql() to avoid modifying original instance
Previous Updates (v2.1.1)
🛠️ Critical Bug Fixes
Table Prefix Handling in JOIN Clauses
Fixed all table prefix issues reported in production environments:
- ✅ Double prefix bug fixed - No more duplicate prefixes in JOIN WHERE clauses
- ✅ Global scopes with JOINs - Global scopes containing JOINs now work correctly
- ✅ Table aliases - Proper handling of aliases in SELECT statements with JOINs
- ✅ Subqueries -
whereIn()with subquery builders handles prefixes correctly
New Model Method: forceFill()
Added Laravel-compatible forceFill() method for bypassing mass assignment:
// Hydrate models from database without checking fillable/guarded $model->forceFill($databaseRow); // Bypasses mass assignment protection
Previous Updates (v2.1.0)
🚀 New Features
Query Caching for exists()
Optimize repeated existence checks with the new opt-in caching mechanism:
$builder = $connection->table('users') ->enableExistsCache(120) // Cache for 2 minutes ->where('email', 'user@example.com'); // First call - hits database $exists = $builder->exists(); // Subsequent calls within 2 minutes - uses cache $exists = $builder->exists(); // No database query!
Global Scopes in Relationships
Relationships now properly inherit global scopes:
// Global scopes automatically apply to relationships $user->posts()->get(); // Includes global scopes from Post model // Or disable for specific queries $user->posts()->withoutGlobalScopes()->get();
Previous Updates (v2.0.7)
- Global Scopes Support - Laravel-style instance-level global scopes
- Nested WHERE Closures - Fixed SQL generation for nested conditions
- Delete Bindings Isolation - Fixed parameter binding in delete operations
- Timestamp Handling - Properly respects
$timestamps = false - Scope Chaining - Full support for chaining custom scope methods
- Aggregate Functions - Automatic detection and handling
- Subquery Support - Fixed whereIn() with Builder subqueries
🔒 PHP 8.4+ Compatibility
- Full compatibility with PHP 8.1, 8.2, 8.3, and 8.4
- All implicit nullable parameter warnings fixed
Requirements
- PHP 8.1, 8.2, 8.3, or 8.4
- PDO extension
- Database-specific PDO driver (pdo_mysql, pdo_pgsql, pdo_sqlite)
Installation
Install via Composer:
composer require marwen-brini/bob-the-builder
Quick Start
use Bob\Database\Connection; // Configure your database connection $connection = new Connection([ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306, 'database' => 'your_database', 'username' => 'your_username', 'password' => 'your_password', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', ]); // Start building queries $users = $connection->table('users') ->where('active', true) ->where('age', '>=', 18) ->orderBy('name') ->limit(10) ->get();
Configuration
Fetch Mode
By default, Bob Query Builder returns query results as associative arrays. You can configure this behavior:
// Option 1: Configure via connection config $connection = new Connection([ 'driver' => 'mysql', 'database' => 'mydb', // ... other config 'fetch' => PDO::FETCH_OBJ, // Return objects instead of arrays ]); // Option 2: Change dynamically at runtime $connection->setFetchMode(PDO::FETCH_OBJ); // Use objects $users = $connection->table('users')->get(); // Returns array of stdClass objects $connection->setFetchMode(PDO::FETCH_ASSOC); // Back to arrays (default) $users = $connection->table('users')->get(); // Returns array of associative arrays
Available fetch modes:
PDO::FETCH_ASSOC- Associative arrays (default)PDO::FETCH_OBJ- stdClass objectsPDO::FETCH_NUM- Numeric arraysPDO::FETCH_BOTH- Both numeric and associative arrays- Any other PDO fetch mode constant
Basic Usage
Select Queries
// Get all records $users = $connection->table('users')->get(); // Get specific columns $users = $connection->table('users') ->select('id', 'name', 'email') ->get(); // Get first record $user = $connection->table('users') ->where('email', 'john@example.com') ->first(); // Get single value $email = $connection->table('users') ->where('id', 1) ->value('email');
Where Clauses
// Basic where $users = $connection->table('users') ->where('status', 'active') ->get(); // Multiple conditions $users = $connection->table('users') ->where('status', 'active') ->where('age', '>', 18) ->get(); // Or where $users = $connection->table('users') ->where('role', 'admin') ->orWhere('role', 'moderator') ->get(); // Where in $users = $connection->table('users') ->whereIn('id', [1, 2, 3]) ->get(); // Where between $users = $connection->table('users') ->whereBetween('age', [18, 65]) ->get(); // Where null $users = $connection->table('users') ->whereNull('deleted_at') ->get();
Joins
// Inner join $users = $connection->table('users') ->join('posts', 'users.id', '=', 'posts.user_id') ->select('users.*', 'posts.title') ->get(); // Left join $users = $connection->table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->get(); // Multiple joins $users = $connection->table('users') ->join('posts', 'users.id', '=', 'posts.user_id') ->join('comments', 'posts.id', '=', 'comments.post_id') ->get();
Aggregates
// Count $count = $connection->table('users')->count(); // Sum $total = $connection->table('orders')->sum('amount'); // Average $avg = $connection->table('products')->avg('price'); // Min/Max $min = $connection->table('products')->min('price'); $max = $connection->table('products')->max('price');
Insert
// Single record $connection->table('users')->insert([ 'name' => 'John Doe', 'email' => 'john@example.com', 'password' => bcrypt('password') ]); // Multiple records $connection->table('users')->insert([ ['name' => 'John', 'email' => 'john@example.com'], ['name' => 'Jane', 'email' => 'jane@example.com'] ]); // Insert and get ID $id = $connection->table('users')->insertGetId([ 'name' => 'John Doe', 'email' => 'john@example.com' ]);
Update
// Update records $affected = $connection->table('users') ->where('id', 1) ->update(['status' => 'active']); // Update with increment $connection->table('posts') ->where('id', 1) ->update(['views' => $connection->raw('views + 1')]);
Delete
// Delete records $deleted = $connection->table('users') ->where('status', 'inactive') ->delete(); // Delete by ID $connection->table('users')->delete(5); // Truncate table $connection->table('users')->truncate();
Transactions
// Basic transaction $connection->transaction(function ($connection) { $connection->table('users')->insert([...]); $connection->table('posts')->insert([...]); }); // Manual transaction control $connection->beginTransaction(); try { // Your queries here $connection->commit(); } catch (Exception $e) { $connection->rollBack(); throw $e; } // Transaction with retries $connection->transaction(function ($connection) { // Your queries here }, attempts: 3);
Raw Expressions
// Raw select $users = $connection->table('users') ->select($connection->raw('COUNT(*) as user_count')) ->get(); // Raw where $users = $connection->table('users') ->where('created_at', '>', $connection->raw('NOW() - INTERVAL 1 DAY')) ->get();
Pagination
// Simple pagination $page = 2; $perPage = 15; $users = $connection->table('users') ->page($page, $perPage) ->get(); // Manual limit/offset $users = $connection->table('users') ->limit(10) ->offset(20) ->get();
Chunking
Process large datasets efficiently:
$connection->table('users')->chunk(100, function ($users) { foreach ($users as $user) { // Process user } });
Cursor Streaming
For extremely large datasets (50k+ rows), use cursor for memory-efficient processing:
// Stream millions of rows with minimal memory usage foreach ($connection->table('users')->cursor() as $user) { // Process one user at a time // Memory usage stays constant regardless of dataset size processUser($user); } // Performance: 1M+ rows/second throughput // Memory: ~8MB for 15,000 rows
Query Debugging
// Enable query logging $connection->enableQueryLog(); // Run queries $users = $connection->table('users')->get(); // Get query log $queries = $connection->getQueryLog(); print_r($queries); // Get SQL without executing $sql = $connection->table('users') ->where('active', true) ->toSql(); echo $sql; // select * from "users" where "active" = ? // Get bindings $bindings = $connection->table('users') ->where('active', true) ->getBindings(); print_r($bindings); // [true]
Database Configuration
MySQL/MariaDB
$connection = new Connection([ 'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306, 'database' => 'database_name', 'username' => 'username', 'password' => 'password', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'options' => [ PDO::ATTR_PERSISTENT => false, ] ]);
PostgreSQL
$connection = new Connection([ 'driver' => 'pgsql', 'host' => '127.0.0.1', 'port' => 5432, 'database' => 'database_name', 'username' => 'username', 'password' => 'password', 'prefix' => '', 'schema' => 'public', ]);
SQLite
$connection = new Connection([ 'driver' => 'sqlite', 'database' => '/path/to/database.sqlite', 'prefix' => '', ]); // In-memory database (great for testing) $connection = new Connection([ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ]);
ORM & Model Features
Model Definition
Bob v2.0 introduces a full ORM layer with Laravel-inspired models:
use Bob\Database\Model; class User extends Model { protected $table = 'users'; protected $primaryKey = 'id'; protected $fillable = ['name', 'email', 'password']; // Define relationships public function posts() { return $this->hasMany(Post::class); } public function profile() { return $this->hasOne(Profile::class); } public function roles() { return $this->belongsToMany(Role::class, 'user_roles'); } }
Relationships
One-to-One (HasOne)
class User extends Model { public function profile() { return $this->hasOne(Profile::class); } } // Usage $user = User::find(1); $profile = $user->profile; // Automatically loads the profile
One-to-Many (HasMany)
class User extends Model { public function posts() { return $this->hasMany(Post::class); } } // Usage $user = User::find(1); $posts = $user->posts; // Returns a Collection of Post models
Many-to-One (BelongsTo)
class Post extends Model { public function author() { return $this->belongsTo(User::class, 'user_id'); } } // Usage $post = Post::find(1); $author = $post->author; // Loads the User model
Many-to-Many (BelongsToMany)
class User extends Model { public function roles() { return $this->belongsToMany(Role::class, 'user_roles', 'user_id', 'role_id'); } } // Usage $user = User::find(1); $roles = $user->roles; // Returns Collection of Role models // Attach/Detach relationships $user->roles()->attach($roleId); $user->roles()->detach($roleId); $user->roles()->sync([1, 2, 3]); // Sync to exact set of IDs
Eager Loading
Prevent N+1 queries with eager loading:
// Load users with their posts and comments $users = User::with('posts.comments')->get(); // Multiple relationships $users = User::with(['posts', 'profile', 'roles'])->get(); // Eager loading with constraints $users = User::with(['posts' => function($query) { $query->where('published', true); }])->get();
Model Queries
Models provide an intuitive ActiveRecord interface:
// Find by primary key $user = User::find(1); // Find or fail (throws exception) $user = User::findOrFail(1); // Create new record $user = User::create([ 'name' => 'John Doe', 'email' => 'john@example.com' ]); // Update existing $user->update(['name' => 'Jane Doe']); // Delete $user->delete(); // Query builder integration $users = User::where('active', true) ->orderBy('created_at', 'desc') ->limit(10) ->get(); // Aggregates $count = User::where('role', 'admin')->count(); $avg = Product::avg('price');
Collections
Model queries return powerful Collection objects:
$users = User::all(); // Collection methods $admins = $users->filter(fn($user) => $user->role === 'admin'); $names = $users->pluck('name'); $grouped = $users->groupBy('role'); $sorted = $users->sortBy('created_at'); // Map over items $emails = $users->map(fn($user) => $user->email); // Check if collection contains item $hasAdmin = $users->contains('role', 'admin');
Database Migrations & Schema Builder (v3.0)
Schema Builder
Create and modify database tables with an expressive, fluent interface:
use Bob\Schema\Schema; // Create a new table Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); // Modify existing table Schema::table('users', function (Blueprint $table) { $table->string('phone')->nullable()->after('email'); $table->index('phone'); }); // Drop table Schema::dropIfExists('users');
WordPress Schema Support
Bob includes specialized helpers for WordPress and WooCommerce table creation:
use Bob\Schema\Schema; // Create WordPress-style post table Schema::createWordPress('custom_posts', function (WordPressBlueprint $table) { $table->wpPost(); // All standard WordPress post columns $table->wpPostIndexes(); // Standard WordPress indexes }); // Create custom meta table Schema::createWordPress('custom_meta', function (WordPressBlueprint $table) { $table->wpMeta('custom'); // Creates: meta_id, custom_id, meta_key, meta_value }); // Create WooCommerce order table Schema::createWordPress('wc_custom_orders', function (WordPressBlueprint $table) { $table->wcOrder(); // All WooCommerce HPOS order columns });
Migration System
Manage database schema changes with version-controlled migrations:
use Bob\Database\Migrations\Migration; use Bob\Schema\Blueprint; use Bob\Schema\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('users'); } }
Running Migrations
use Bob\Database\Migrations\MigrationRunner; use Bob\Database\Migrations\MigrationRepository; use Bob\Database\Connection; $connection = new Connection([/* config */]); $repository = new MigrationRepository($connection, 'migrations'); $runner = new MigrationRunner($connection, $repository, ['/path/to/migrations']); // Run pending migrations $runner->run(); // Rollback last batch $runner->rollback(); // Rollback all migrations $runner->reset(); // Drop all tables and re-run migrations $runner->fresh(); // Rollback and re-run all migrations $runner->refresh(); // Check migration status $status = $runner->status();
Migration Features
- Dependency Resolution - Migrations can declare dependencies on other migrations
- Transaction Support - Run migrations within database transactions
- Batch Tracking - Track which migrations ran together
- Lifecycle Hooks -
before()andafter()methods for setup/cleanup - Event System - Hook into migration events for logging and monitoring
- Pretend Mode - See what migrations would do without running them
- Version Control - Each migration is tracked with execution time and batch number
Schema Inspector
Reverse engineer existing databases and generate migration files:
use Bob\Schema\Inspector; $inspector = new Inspector($connection); // Get all tables $tables = $inspector->getTables(); // Get table structure $columns = $inspector->getColumns('users'); $indexes = $inspector->getIndexes('users'); $foreignKeys = $inspector->getForeignKeys('users'); // Generate migration from existing table $migration = $inspector->generateMigration('users'); file_put_contents('2024_01_01_000000_create_users_table.php', $migration);
Column Types
Bob supports all standard database column types:
// Numeric types $table->id(); // Auto-incrementing BIGINT $table->bigInteger('votes'); $table->integer('count'); $table->smallInteger('votes'); $table->tinyInteger('active'); $table->decimal('amount', 8, 2); $table->float('amount'); $table->double('amount'); // String types $table->string('name', 100); $table->text('description'); $table->longText('content'); $table->char('code', 4); // Date/Time types $table->date('birthday'); $table->dateTime('created_at'); $table->timestamp('updated_at'); $table->time('sunrise'); $table->timestamps(); // created_at + updated_at // Other types $table->boolean('active'); $table->json('metadata'); $table->binary('data'); $table->uuid('identifier'); $table->enum('status', ['active', 'inactive']); // Column modifiers $table->string('email')->nullable(); $table->string('name')->default('Guest'); $table->string('slug')->unique(); $table->integer('position')->unsigned(); $table->text('bio')->comment('User biography');
Indexes and Constraints
// Indexes $table->primary('id'); $table->unique('email'); $table->index('status'); $table->index(['user_id', 'created_at']); // Foreign keys $table->foreign('user_id') ->references('id') ->on('users') ->onDelete('cascade') ->onUpdate('cascade'); // Drop constraints $table->dropPrimary('users_id_primary'); $table->dropUnique('users_email_unique'); $table->dropIndex('users_status_index'); $table->dropForeign('posts_user_id_foreign');
Advanced Features
Query Builder Cloning
$baseQuery = $connection->table('users')->where('active', true); // Clone for variations $admins = $baseQuery->clone()->where('role', 'admin')->get(); $users = $baseQuery->clone()->where('role', 'user')->get();
Subqueries
$subquery = $connection->table('posts') ->select('user_id') ->where('published', true); $users = $connection->table('users') ->whereIn('id', $subquery) ->get();
Custom Grammars
Extend the grammar for custom SQL dialects:
use Bob\Query\Grammar; class CustomGrammar extends Grammar { // Override methods for custom SQL generation } $connection->setQueryGrammar(new CustomGrammar());
Testing
Run the test suite:
# Run all tests composer test # Run with coverage composer test:coverage # Run specific test suite vendor/bin/pest tests/Integration # Run with verbose output vendor/bin/pest -vvv
Performance Benchmarks
Bob Query Builder is highly optimized for real-world applications:
Query Building Performance
- Simple SELECT: ~0.02ms average overhead
- Complex queries with joins: ~0.1ms average overhead
- Subqueries: ~0.07ms average overhead
- All query types: <10ms overhead guaranteed
Large Dataset Handling
- Streaming: 1M+ rows per second throughput
- Memory usage: ~8MB for 15,000 rows with cursor
- 50,000 rows: Handled efficiently with <30MB memory
- Chunk processing: Process millions of rows without memory issues
Optimization Features
The query builder includes several optimization features:
- Prepared Statement Caching: Reuses prepared statements for identical queries
- Connection Pooling: Efficient connection management
- Query Result Caching: Optional caching of query results
- Lazy Loading: Use
cursor()for memory-efficient iteration - Bulk Operations: Optimized bulk inserts and updates
- Statement Caching: Second run of cached statements is significantly faster
Use Cases
Bob Query Builder is perfect for:
- WordPress Plugins - Modern query building without the overhead
- Legacy PHP Applications - Modernize database interactions incrementally
- Microservices - Lightweight, efficient database layer
- API Development - Clean, readable query construction
- Any PHP Project - From simple scripts to complex applications
Integration Examples
WordPress / Quantum ORM
use Bob\Database\Connection; $connection = new Connection([ 'driver' => 'mysql', 'host' => DB_HOST, 'database' => DB_NAME, 'username' => DB_USER, 'password' => DB_PASSWORD, 'prefix' => $wpdb->prefix, ]); // Now use modern query building in WordPress! $posts = $connection->table('posts') ->where('post_status', 'publish') ->orderBy('post_date', 'desc') ->limit(10) ->get();
Standalone PHP Application
use Bob\Database\Connection; $connection = new Connection([ 'driver' => 'sqlite', 'database' => 'database.sqlite', ]); $users = $connection->table('users') ->where('active', true) ->get();
Integration with Any Framework
Bob Query Builder can be registered as a service in any dependency injection container:
// In your service provider or bootstrap $container->singleton(Connection::class, function () { return new Connection(config('database')); });
📚 Documentation
Full documentation is available at https://marwen-brini.github.io/bob-the-builder/
The documentation includes:
- Getting Started Guide
- Complete API Reference
- Database-specific Features
- Performance Optimization Tips
- WordPress Integration Guide
- CLI Tool Usage
- Migration from Other Query Builders
- Troubleshooting Guide
Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
Testing Requirements
- Tests must be written before implementation (TDD)
- All tests must pass before merging
- Maintain 100% code coverage
- Follow PSR-12 coding standards
License
The Bob Query Builder is open-sourced software licensed under the MIT license.
Project Repository
🔗 GitHub: https://github.com/Marwen-Brini/bob-the-builder
Credits
- Originally built to enhance Quantum ORM, but designed as a standalone solution for ANY PHP project
- Inspired by Laravel's Eloquent Query Builder
- Designed with modern PHP best practices and 100% test coverage
- Built with love for the PHP community
Support
For bugs and feature requests, please use the GitHub issues.
Roadmap
Completed ✅
- Core query building functionality
- Multi-database support (MySQL, PostgreSQL, SQLite)
- Transaction support
- Prepared statement caching
- Query result caching
- Connection pooling
- Performance profiling
- PSR-3 logging integration
- Slow query detection
- Memory-efficient streaming (cursor/chunk)
- CLI tools for testing and query building
- Comprehensive test suite (1644 tests)
- Performance benchmarks
v3.0 - Completed ✅
- Schema builder with fluent interface
- Migration system with dependency resolution
- WordPress/WooCommerce schema helpers
- Schema inspector for reverse engineering
- Migration event system
- Transaction support for migrations
Planned Features
- Database seeding system
- Query builder macros/extensions
- Additional database support (SQL Server, Oracle)
- Query builder IDE helpers
- Advanced migration features (squashing, etc.)