monkeyscloud / monkeyslegion-query
Performance-first Query Builder & Micro-ORM for MonkeysLegion v2
Package info
github.com/MonkeysCloud/MonkeysLegion-Query
pkg:composer/monkeyscloud/monkeyslegion-query
2.0.1
2026-04-16 03:46 UTC
Requires
- php: ^8.4
- ext-pdo: *
- monkeyscloud/monkeyslegion-database: ^2.0
- monkeyscloud/monkeyslegion-entity: ^2.0
- psr/log: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.2
- squizlabs/php_codesniffer: ^4.0
- dev-2.x-dev / 2.0.x-dev
- 2.0.1
- 2.0.0
- dev-main / 1.0.x-dev
- 1.0.26
- 1.0.25
- 1.0.24
- 1.0.23
- v1.0.22
- 1.0.21
- 1.0.20
- 1.0.19
- 1.0.18
- 1.0.17
- 1.0.16
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-copilot/review-performance-security-improvements
- dev-copilot/improve-performance-for-high-traffic-websites
- dev-perf/phase2-schema-cache-eager-loading
- dev-fix/query-performance-optimization
- dev-fix/postgres-compatibility
- dev-fix-many-to-many
- dev-patch
- dev-dev
This package is auto-updated.
Last update: 2026-04-16 03:46:37 UTC
README
Performance-first Query Builder & Micro-ORM for the MonkeysLegion framework.
Architecture
QueryBuilder (Fluent API)
→ typed Clause VOs (zero string work)
→ QueryCompiler (stateless, cached)
→ GrammarInterface (MySQL/MariaDB, PostgreSQL, SQLite)
→ ConnectionManagerInterface (read/write routing)
EntityRepository (single class)
→ IdentityMap (same row → same object)
→ UnitOfWork (batched writes)
→ EntityHydrator (cached reflection)
Key Features
| Feature | Description |
|---|---|
| Performance-first | Structural SQL caching (xxh128), statement reuse, zero-copy bindings |
| 4 DB engines | MySQL, MariaDB, PostgreSQL, SQLite — full grammar implementations |
| Read/write routing | Automatic: SELECTs → read(), DML → write() via ConnectionManagerInterface |
| PHP 8.4 | Property hooks, asymmetric visibility, readonly classes, backed enums |
| Identity map | Same row always returns same object instance |
| Unit of Work | persist() / remove() / flush() — batched writes in one transaction |
| Cursor pagination | Constant-memory traversal of large datasets |
| CTE builder | Standard and recursive CTEs across all 4 engines |
| Vector search | pgvector, MySQL 9.x VEC_DISTANCE, with fallbacks |
| #[Scope] attribute | Global and per-query scopes on repository methods |
Installation
composer require monkeyscloud/monkeyslegion-query:2.x-dev
Quick Start
Query Builder
use MonkeysLegion\Query\Query\QueryBuilder; // Inject ConnectionManagerInterface via DI $qb = new QueryBuilder($connectionManager); // SELECT $users = $qb->from('users') ->select(['id', 'name', 'email']) ->where('status', '=', 'active') ->where('age', '>', 18) ->orderByDesc('created_at') ->limit(25) ->get(); // First row $user = $qb->from('users') ->where('email', '=', 'alice@example.com') ->first(); // Aggregates $count = $qb->from('orders')->where('status', '=', 'pending')->count(); $total = $qb->from('orders')->sum('amount'); // INSERT $id = $qb->from('users')->insert([ 'name' => 'Alice', 'email' => 'alice@example.com', ]); // UPDATE $qb->from('users') ->where('id', '=', $id) ->update(['status' => 'verified']); // DELETE $qb->from('sessions') ->where('expired_at', '<', date('Y-m-d')) ->delete();
Joins
// Simple join $qb->from('users', 'u') ->leftJoinOn('orders', 'u.id', '=', 'orders.user_id', 'o') ->select(['u.name', 'o.total']) ->get(); // Complex join with callback $qb->from('users', 'u') ->join('orders', fn($j) => $j ->on('u.id', '=', 'o.user_id') ->where('o.status', '=', 'completed'), alias: 'o', ) ->get();
Where Clauses
$qb->from('users') ->where('status', '=', 'active') // standard ->orWhere('role', '=', 'admin') // OR ->whereIn('id', [1, 2, 3]) // IN ->whereNotIn('status', ['banned']) // NOT IN ->whereBetween('age', 18, 65) // BETWEEN ->whereNull('deleted_at') // IS NULL ->whereNotNull('email') // IS NOT NULL ->get();
Repository
use MonkeysLegion\Query\Repository\EntityRepository; class UserRepository extends EntityRepository { protected string $table = 'users'; protected string $entityClass = User::class; } // Find $user = $repo->find(1); $user = $repo->findOrFail(1); // Batch loading (single WHERE IN query) $users = $repo->findByIds([1, 2, 3]); // Criteria-based $admins = $repo->findBy(['role' => 'admin'], ['name' => 'ASC'], limit: 10); $alice = $repo->findOneBy(['email' => 'alice@example.com']); // Unit of Work $user = new User(); $user->name = 'Bob'; $repo->persist($user); $repo->flush(); // INSERT in transaction // Cursor pagination (constant memory) $page = $repo->cursorPaginate(cursor: null, perPage: 25); // $page = ['data' => [...], 'nextCursor' => 26, 'hasMore' => true]
Common Table Expressions
use MonkeysLegion\Query\Query\CteBuilder; $cte = new CteBuilder(); $cte->add('active_users', 'SELECT * FROM users WHERE status = ?', ['active']); // Recursive CTE (tree structures) $cte->add( name: 'category_tree', sql: 'SELECT id, parent_id FROM categories WHERE id = ? ' . 'UNION ALL ' . 'SELECT c.id, c.parent_id FROM categories c ' . 'JOIN category_tree ct ON c.parent_id = ct.id', bindings: [$rootId], recursive: true, );
Vector Search
use MonkeysLegion\Query\Query\VectorSearch; // Nearest neighbors using pgvector (PostgreSQL) $expr = VectorSearch::distance('embedding', $queryVector, DatabaseDriver::PostgreSQL); // Produces: embedding <-> '[1.0,2.0,3.0]' // Cosine similarity $expr = VectorSearch::distance('embedding', $vector, DatabaseDriver::PostgreSQL, 'cosine'); // Produces: embedding <=> '[1.0,2.0,3.0]'
Performance
| Metric | v1 | v2 |
|---|---|---|
| Test suite (156 tests) | ~120ms | 41ms |
| Code size | 10,500 lines / 19 files | 3,600 lines / 24 files |
| Inheritance depth | 3 classes | 1 class |
| Schema queries at build | Per column | Zero |
| SQL compilation | Every execution | Cached (xxh128) |
| PDOStatement | New per query | Cached per connection |
Database Compatibility
| Feature | MySQL 8+ | MariaDB 10.2+ | PostgreSQL | SQLite 3.35+ |
|---|---|---|---|---|
| Query builder | ✅ | ✅ | ✅ | ✅ |
| Upsert | ON DUPLICATE KEY | ON DUPLICATE KEY | ON CONFLICT | ON CONFLICT |
| RETURNING | ❌ | ❌ | ✅ | ✅ |
| JSON path | ->> | ->> | ->> / #>> | json_extract |
| CTE | ✅ | ✅ | ✅ | ✅ |
| Recursive CTE | ✅ | ✅ | ✅ | ✅ |
| Vector search | VEC_DISTANCE* | ❌ | pgvector | ❌ |
| Identifier quoting | `backtick` | `backtick` | "double" | "double" |
Requirements
- PHP 8.4+
monkeyscloud/monkeyslegion-databasev2monkeyscloud/monkeyslegion-entityv1+- PDO extension
License
MIT © MonkeysCloud