PHP code example of flowpack / query-object-builder
1. Go to this page and download the library: Download flowpack/query-object-builder library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
flowpack / query-object-builder example snippets
use Flowpack\QueryObjectBuilder\PostgreSQL\Q;
$q = Q::select(Q::n('name'), Q::n('email'))
->from(Q::n('users'))
->where(Q::n('active')->eq(Q::arg(true)))
->orderBy(Q::n('name'));
[$sql, $args] = Q::build($q)->toSql();
echo $sql; // SELECT name,email FROM users WHERE active = $1 ORDER BY name
var_dump($args); // [true]
use Flowpack\QueryObjectBuilder\MySQL\Q;
$q = Q::select(Q::n('name'), Q::n('email'))
->from(Q::n('users'))
->where(Q::n('active')->eq(Q::arg(true)))
->orderBy(Q::n('name'));
[$sql, $args] = Q::build($q)->toSql();
echo $sql; // SELECT name,email FROM users WHERE active = ? ORDER BY name
var_dump($args); // [true]
use Flowpack\QueryObjectBuilder\MySQL\Q;
use Flowpack\QueryObjectBuilder\MySQL\Builder\Target;
$q = Q::select(Q::n('id'))->from(Q::n('t'))->forShare(); // FOR SHARE is MySQL-only
Q::build($q)->withValidateTarget(Target::mysql())->toSql(); // ok
Q::build($q)->withValidateTarget(Target::mariaDb())->toSql(); // throws QueryBuilderException:
// "FOR SHARE
// PostgreSQL: GROUP BY ROLLUP (...)
$q = Q::select(Q::n('department'), Q::n('job_title'), Q\Func::sum(Q::n('salary')))
->from(Q::n('employees'))
->groupBy()->rollup(Q::exps(Q::n('department')), Q::exps(Q::n('job_title')));
// SELECT department, job_title, sum(salary) FROM employees
// GROUP BY ROLLUP (department, job_title)
// MySQL / MariaDB: GROUP BY ... WITH ROLLUP
$q = Q::select(Q::n('department'), Q::n('job_title'), Q\Func::sum(Q::n('salary')))
->from(Q::n('employees'))
->groupBy(Q::n('department'), Q::n('job_title'))->withRollup();
// SELECT department, job_title, SUM(salary) FROM employees
// GROUP BY department, job_title WITH ROLLUP
use Flowpack\QueryObjectBuilder\MySQL\Q;
// Running total: ROWS UNBOUNDED PRECEDING
$q = Q::select(
Q\Func::sum(Q::n('val'))->over()
->partitionBy(Q::n('subject'))->orderBy(Q::n('time'))
->rows(Q::unboundedPreceding()),
)->from(Q::n('observations'));
// SELECT SUM(val) OVER (PARTITION BY subject ORDER BY time ROWS UNBOUNDED PRECEDING) FROM observations
// Moving average: ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
$q = Q::select(
Q\Func::avg(Q::n('val'))->over()
->partitionBy(Q::n('subject'))->orderBy(Q::n('time'))
->rows(Q::preceding(Q::int(1)), Q::following(Q::int(1))),
)->from(Q::n('observations'));
// SELECT AVG(val) OVER (PARTITION BY subject ORDER BY time ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM observations
$q = Q::selectJson(
// PostgreSQL: Q\Func::jsonBuildObject() — MySQL / MariaDB: Q\Func::jsonObject()
Q\Func::jsonObject()
->prop('id', Q::n('authors.author_id'))
->prop('name', Q::n('authors.name')),
)
->from(Q::n('authors'))
->where(Q::n('authors.author_id')->eq(Q::arg(123)));
// The builder is a blueprint — add to the JSON selection later:
$q = $q->applySelectJson(fn ($obj) => $obj->prop('postCount', Q\Func::count(Q::n('posts'))));
// PostgreSQL: json_agg(...)
$q = Q::select(
Q::n('department'),
Q\Func::jsonAgg(
Q\Func::jsonBuildObject()->prop('name', Q::n('name'))->prop('salary', Q::n('salary')),
)->orderBy(Q::n('name')),
)->from(Q::n('employees'))->groupBy(Q::n('department'));
// SELECT department, json_agg(json_build_object('name', name, 'salary', salary) ORDER BY name)
// FROM employees GROUP BY department
// MySQL / MariaDB: JSON_ARRAYAGG(...); COALESCE with JSON_ARRAY() to avoid NULL on empty sets
$q = Q::select(
Q::n('department'),
Q::coalesce(
Q\Func::jsonArrayAgg(
Q\Func::jsonObject()->prop('name', Q::n('name'))->prop('salary', Q::n('salary')),
),
Q\Func::jsonArray(),
),
)->from(Q::n('employees'))->groupBy(Q::n('department'));
// SELECT department, COALESCE(JSON_ARRAYAGG(JSON_OBJECT('name', name, 'salary', salary)), JSON_ARRAY())
// FROM employees GROUP BY department
use Flowpack\QueryObjectBuilder\MySQL\Q;
// MySQL: the -> and ->> operators
$q = Q::select(Q::n('doc')->jsonExtract(Q::string('$.name')))->from(Q::n('t'));
// SELECT doc -> '$.name' FROM t
// MariaDB: the function form (also works on MySQL)
$q = Q::select(Q\Func::jsonExtract(Q::n('doc'), Q::string('$.name')))->from(Q::n('t'));
// SELECT JSON_EXTRACT(doc, '$.name') FROM t
use Flowpack\QueryObjectBuilder\MySQL\Q;
$q = Q::with('stale')->as(Q::select(Q::n('id'))->from(Q::n('sessions'))->where(Q::n('expired')->eq(Q::int(1))))
->deleteFrom(Q::n('users'))->where(Q::n('id')->in(Q::select(Q::n('id'))->from(Q::n('stale'))));
// WITH stale AS (SELECT id FROM sessions WHERE expired = 1) DELETE FROM users WHERE id IN (SELECT id FROM stale)
// ok against Target::mysql() and Target::mariaDb('12.3'); reported against Target::mariaDb('11.4')
// PostgreSQL: INSERT ... ON CONFLICT ... DO UPDATE
use Flowpack\QueryObjectBuilder\PostgreSQL\Q;
$q = Q::insertInto(Q::n('distributors'))
->columnNames('did', 'dname')
->values(Q::int(5), Q::string('Gizmo Transglobal'))
->onConflict(Q::n('did'))->doUpdate()
->set('dname', Q::n('EXCLUDED.dname'));
// INSERT INTO distributors (did, dname) VALUES (5, 'Gizmo Transglobal')
// ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname
// MySQL / MariaDB: INSERT ... ON DUPLICATE KEY UPDATE
use Flowpack\QueryObjectBuilder\MySQL\Q;
// MySQL: alias the proposed row with AS new, reference it as new.col
$q = Q::insertInto(Q::n('t'))
->columnNames('id', 'hits')->values(Q::arg(1), Q::arg(10))->as('new')
->onDuplicateKeyUpdate()->set('hits', Q::n('new.hits'));
// INSERT INTO t (id,hits) VALUES (?,?) AS new ON DUPLICATE KEY UPDATE hits = new.hits
// Portable: the VALUES(col) function works on both engines
$q = Q::insertInto(Q::n('t'))
->columnNames('id', 'hits')->values(Q::arg(1), Q::arg(10))
->onDuplicateKeyUpdate()->set('hits', Q::values('hits'));
// INSERT INTO t (id,hits) VALUES (?,?) ON DUPLICATE KEY UPDATE hits = VALUES(hits)
// PostgreSQL
use Flowpack\QueryObjectBuilder\PostgreSQL\Q;
$q = Q::insertInto(Q::n('users'))
->columnNames('name')->values(Q::arg('Jane'))
->returning(Q::n('id'), Q::n('created_at'));
// INSERT INTO users (name) VALUES ($1) RETURNING id, created_at
// MariaDB (INSERT / REPLACE / single-table DELETE) — reported against Target::mysql()
use Flowpack\QueryObjectBuilder\MySQL\Q;
$q = Q::insertInto(Q::n('t'))->columnNames('a')->values(Q::arg(1))
->returning(Q::n('id'))->as('new_id');
// INSERT INTO t (a) VALUES (?) RETURNING id AS new_id
// PostgreSQL
$q = Q::update(Q::n('employees'))->as('e')
->set('department_name', Q::n('d.name'))
->from(Q::n('departments'))->as('d')
->where(Q::n('e.department_id')->eq(Q::n('d.id')));
// UPDATE employees AS e SET department_name = d.name FROM departments AS d WHERE e.department_id = d.id
// MySQL / MariaDB
$q = Q::update(Q::n('t1'))
->leftJoin(Q::n('t2'))->on(Q::n('t1.id')->eq(Q::n('t2.id')))
->set('t1.col1', Q::n('t2.col1'))
->where(Q::n('t2.col2')->isNull());
// UPDATE t1 LEFT JOIN t2 ON t1.id = t2.id SET t1.col1 = t2.col1 WHERE t2.col2 IS NULL
// PostgreSQL
$q = Q::deleteFrom(Q::n('films'))
->using(Q::n('producers'))
->where(Q::n('producer_id')->eq(Q::n('producers.id')));
// DELETE FROM films USING producers WHERE producer_id = producers.id
// MySQL / MariaDB
$q = Q::deleteFrom(Q::n('t1'))
->leftJoin(Q::n('t2'))->on(Q::n('t1.id')->eq(Q::n('t2.id')))
->where(Q::n('t2.id')->isNull());
// DELETE t1.* FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NULL
// PostgreSQL: the :: operator via ->cast()
$q = Q::select(Q::n('articles.content')->cast('text'))->from(Q::n('articles'));
// SELECT articles.content::text FROM articles
// MySQL / MariaDB: CAST / CONVERT through the facade
$q = Q::select(Q::cast(Q::n('a'), 'UNSIGNED'), Q::convert(Q::n('a'), 'DECIMAL(10,2)'));
// SELECT CAST(a AS UNSIGNED), CONVERT(a, DECIMAL(10,2))
// PostgreSQL
$q = Q::select(Q\Func::upper(Q::n('name')), Q\Func::extract('year', Q::n('created_at')))
->from(Q::n('users'));
// SELECT upper(name), EXTRACT(year FROM created_at) FROM users
// MySQL / MariaDB
$q = Q::select(Q\Func::upper(Q::n('name')), Q\Func::dateAdd(Q::n('created'), Q::interval(Q::int(1), 'DAY')))
->from(Q::n('users'));
// SELECT UPPER(name), DATE_ADD(created, INTERVAL 1 DAY) FROM users
use Flowpack\QueryObjectBuilder\MySQL\Q;
// MySQL: FOR SHARE (+ of() / nowait() / skipLocked())
$q = Q::select(Q::n('id'))->from(Q::n('t'))->forShare()->of('t')->nowait();
// SELECT id FROM t FOR SHARE OF t NOWAIT
// MariaDB: LOCK IN SHARE MODE
$q = Q::select(Q::n('id'))->from(Q::n('t'))->lockInShareMode();
// SELECT id FROM t LOCK IN SHARE MODE
$q = Q::select(Q::n('*'))
->from(Q::n('users'))
->where(Q::and(
Q::n('name')->like(Q::arg('John%')),
Q::n('active')->eq(Q::arg(true)),
));
[$sql, $args] = Q::build($q)->toSql();
// PostgreSQL: SELECT * FROM users WHERE name LIKE $1 AND active = $2 args: ['John%', true]
// MySQL: SELECT * FROM users WHERE name LIKE ? AND active = ? args: ['John%', true]
sql
-- PostgreSQL
SELECT * FROM employees
WHERE (firstname LIKE $1 OR lastname LIKE $2) AND active = true
-- MySQL / MariaDB
SELECT * FROM employees
WHERE (firstname LIKE ? OR lastname LIKE ?) AND active = TRUE
sql
-- PostgreSQL
SELECT department, count(*) AS n FROM employees
GROUP BY department HAVING count(*) > 5
-- MySQL / MariaDB
SELECT department, COUNT(*) AS n FROM employees
GROUP BY department HAVING COUNT(*) > 5
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.