jardissupport/dbquery

Fluent SQL query builder with CTEs, window functions, subqueries, and JSON support for MySQL, MariaDB, PostgreSQL, and SQLite

Maintainers

Package info

github.com/jardisSupport/dbquery

pkg:composer/jardissupport/dbquery

Statistics

Installs: 287

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-03-31 07:37 UTC

This package is auto-updated.

Last update: 2026-03-31 07:39:40 UTC


README

Build Status License: PolyForm Shield PHP Version PHPStan Level PSR-12 Coverage

Part of the Jardis Business Platform — Enterprise-grade PHP components for Domain-Driven Design

Fluent SQL query builder that generates dialect-aware SQL for MySQL, MariaDB, PostgreSQL, and SQLite. Full support for CTEs, window functions, subqueries, JSON columns, and prepared statements. SQL injection protection built in.

Features

  • Dialect-Aware SQL — generates correct syntax for MySQL, MariaDB, PostgreSQL, and SQLite from a single builder
  • CTEswith() and withRecursive() for common table expressions
  • Window FunctionsselectWindow(), window(), and selectWindowRef() for analytics queries
  • Subqueries — subqueries in FROM, JOIN constraints, SELECT columns, and WHERE EXISTS / NOT EXISTS
  • JSON Column SupportwhereJson(), andJson(), orJson(), havingJson() for structured JSON field conditions
  • Union / Union Allunion() and unionAll() compose multiple SELECT statements
  • Prepared Statementssql($dialect, prepared: true) returns a DbPreparedQueryInterface with bound parameters
  • SQL Injection Validation — bracket and expression validation built into sql() before generation
  • INSERT Conflict HandlingDbInsert supports ON DUPLICATE KEY (MySQL) and ON CONFLICT (PostgreSQL)

Installation

composer require jardissupport/dbquery

Quick Start

use JardisSupport\DbQuery\DbQuery;

$query = (new DbQuery())
    ->select('id, name, email')
    ->from('users')
    ->where('status')->equals('active')
    ->and('created_at')->greaterEquals('2024-01-01')
    ->orderBy('name')
    ->limit(50);

// Generate prepared SQL for MySQL
$prepared = $query->sql('mysql', prepared: true);
// $prepared->sql()      → "SELECT id, name, email FROM users WHERE status = ? AND created_at >= ? ORDER BY name ASC LIMIT 50"
// $prepared->bindings() → ['active', '2024-01-01']

Advanced Usage

use JardisSupport\DbQuery\DbQuery;
use JardisSupport\DbQuery\DbInsert;

// CTE with recursive traversal
$cte = (new DbQuery())
    ->select('id, parent_id, name, 0 AS depth')
    ->from('categories')
    ->where('parent_id')->isNull()
    ->union(
        (new DbQuery())
            ->select('c.id, c.parent_id, c.name, r.depth + 1')
            ->from('categories', 'c')
            ->innerJoin('category_tree', 'c.parent_id = r.id', 'r')
    );

$query = (new DbQuery())
    ->withRecursive('category_tree', $cte)
    ->select('id, name, depth')
    ->from('category_tree')
    ->orderBy('depth')
    ->orderBy('name');

// Window function for ranking
$ranked = (new DbQuery())
    ->select('id, customer_id, total')
    ->selectWindow('ROW_NUMBER', 'row_num')
        ->over()
        ->partitionBy('customer_id')
        ->orderBy('total', 'DESC')
        ->end()
    ->from('orders');

// JSON column condition (PostgreSQL)
$query = (new DbQuery())
    ->select('id, payload')
    ->from('events')
    ->whereJson('payload')->path('$.type')->equals('order.created')
    ->andJson('payload')->path('$.amount')->greaterEquals(100);

// INSERT with conflict resolution
$insert = (new DbInsert())
    ->into('products')
    ->fields('sku', 'name', 'price')
    ->values('ABC-001', 'Widget', 9.99)
    ->onDuplicateKey(['name', 'price']);

$sql = $insert->sql('mysql', prepared: true);

Documentation

Full documentation, guides, and API reference:

docs.jardis.io/support/dbquery

License

This package is licensed under the PolyForm Shield License 1.0.0. Free for all use except building competing frameworks or developer tooling.

Jardis · Documentation · Headgent