Skip to content

Commit

Permalink
QueryBuilder fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesread committed Sep 5, 2023
1 parent 3037f41 commit 4ce6c53
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 22 deletions.
64 changes: 50 additions & 14 deletions src/main/php/libAllure/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class QueryBuilder
private $lastAliasUsed = null;
private $lastJoinedTable = null;

private $tableAliases = [];

Check failure on line 19 in src/main/php/libAllure/QueryBuilder.php

View workflow job for this annotation

GitHub Actions / build

Property libAllure\QueryBuilder::$tableAliases is never read, only written.

public function __construct($verb = 'SELECT')
{
$verb = strtoupper($verb);
Expand All @@ -26,7 +28,7 @@ public function __construct($verb = 'SELECT')
public function orderBy(string ...$fields)
{
foreach ($fields as $arg) {
$arg = $this->addFieldPrefix($arg);
$arg = $this->from['alias'] . '.' . $arg;

array_push($this->orderBy, $arg);
}
Expand All @@ -36,10 +38,12 @@ public function orderBy(string ...$fields)

public function from(string $tableName, string $alias = null, string $database = null)
{
if ($alias == null) {
$alias = substr($tableName, 0, 1);
if ($this->from !== null) {
throw new \Exception('QB from() already used');
}

$alias = $this->buildTableAlias($tableName, $alias, $database);

$this->from = array(
'alias' => $alias,
'table' => $tableName,
Expand Down Expand Up @@ -163,36 +167,61 @@ private function quoteValue($value)
}
}

public function join($tbl, $alias = null)
public function buildTableAlias($tbl, $alias, $database)
{
return $this->leftJoin($tbl, $alias);
$existingAliases = array_column($this->joins, 'alias');

if (isset($this->from)) {
$existingAliases[] = $this->from['alias'];
}

if ($alias == null) {
for ($i = 0; $i < strlen($tbl); $i++) {
$alias = $tbl[$i];

if (!in_array($alias, $existingAliases)) {
return $alias;
}
}

throw new Exception('Unique alias not possible, tbl: ' . $tbl);

Check failure on line 187 in src/main/php/libAllure/QueryBuilder.php

View workflow job for this annotation

GitHub Actions / build

Instantiated class libAllure\Exception not found.

Check failure on line 187 in src/main/php/libAllure/QueryBuilder.php

View workflow job for this annotation

GitHub Actions / build

Throwing object of an unknown class libAllure\Exception.
}


return $alias;
}

public function leftJoin($tbl, $alias = null)
public function join($tbl, $alias = null, $database = null)
{
return $this->joinImpl('LEFT', $tbl, $alias);
return $this->leftJoin($tbl, $alias, $database);
}

public function joinImpl($direction, $tbl, $alias = null)
public function leftJoin($tbl, $alias = null, $database = null)
{
if ($alias == null) {
$alias = substr($tbl, 0, 1);
}
return $this->joinImpl('LEFT', $tbl, $alias, $database);
}

public function joinImpl($direction, $tbl, $alias = null, $database = null)
{
$alias = $this->buildTableAlias($tbl, $alias, $database);

$this->joins[$tbl] = array(
'direction' => $direction,
'database' => $database,
'table' => $tbl,
'alias' => $alias
);

$this->lastJoinedTable = $tbl;
$this->lastAliasUsed = $alias;

return $this;
}

public function joinedTable($tbl)
public function joinedTable($tbl = null)
{
$this->lastJoinedTable = $tbl;
$this->lastAliasUsed = $this->joins[$tbl]['alias'];

return $this;
}
Expand Down Expand Up @@ -225,7 +254,7 @@ public function groupBy($field)

public function group($field)
{
$this->group = $field;
$this->group = $this->addFieldPrefix($field);

return $this;
}
Expand Down Expand Up @@ -276,7 +305,14 @@ public function buildJoins()
$ret = '';

foreach ($this->joins as $join) {
$ret .= ' ' . $join['direction'] . ' JOIN ' . $join['table'] . ' ' . $join['alias'] . ' ' . $this->buildJoinConditions($join['table']);
$db = '';

if (!empty($join['database'])) {
$db = $join['database'] . '.';
}


$ret .= ' ' . $join['direction'] . ' JOIN ' . $db . $join['table'] . ' ' . $join['alias'] . ' ' . $this->buildJoinConditions($join['table']);
}

return $ret;
Expand Down
37 changes: 29 additions & 8 deletions src/test/php/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public function testSelectDifferentDatabase()
public function testSelectOrderId() {
$qb = new QueryBuilder();
$qb->from('users')->fields('u.username');
$qb->orderBy('u.id');
$qb->orderBy('id');

$this->assertEquals('SELECT u.username FROM users u ORDER BY u.id', $qb->build());
}

public function testAutoPrefixFields() {
$qb = new QueryBuilder();
$qb->from('users')->fields('id', 'forename');
$qb->from('users')->fields('surname');
$qb->fields('surname');
$qb->orderBy('id');

$this->assertEquals('SELECT u.id, u.forename, u.surname FROM users u ORDER BY u.id', $qb->build());
Expand All @@ -59,21 +59,20 @@ public function testJoin() {
$qb = new QueryBuilder();
$qb->from('users')->fields('email', array('count(o.id)', 'orderCount'));
$qb->leftJoin('orders')->onEq('o.uid', 'u.id');
$qb->orderBy('!orderCount');
$qb->orderBy('orderCount');

$this->assertEquals('SELECT u.email, count(o.id) AS orderCount FROM users u LEFT JOIN orders o ON o.uid = u.id ORDER BY orderCount', $qb->build());
$this->assertEquals('SELECT u.email, count(o.id) AS orderCount FROM users u LEFT JOIN orders o ON o.uid = u.id ORDER BY u.orderCount', $qb->build());
}

public function testMultiJoin() {
$qb = new QueryBuilder();
$qb->from('users')->fields('email', array('count(o.id)', 'orderCount'), 'g.title');
$qb->from('users')->fields('email', array('count(o.id)', 'orderCount'), 'forename', 'surname');
$qb->leftJoin('orders')->onEq('o.uid', 'u.id');
$qb->leftJoin('groups')->onEq('u.group', 'g.id');
$qb->leftJoin('groups')->onEq('u.group', 'g.id')->fields('title');
$qb->joinedTable('orders')->onGt('o.date', ':date');
$qb->fields('forename', 'surname');
$qb->orderBy('email');

$this->assertEquals('SELECT u.email, count(o.id) AS orderCount, g.title, u.forename, u.surname FROM users u LEFT JOIN orders o ON o.uid = u.id AND o.date > :date LEFT JOIN groups g ON u.group = g.id ORDER BY u.email', $qb->build());
$this->assertEquals('SELECT u.email, count(o.id) AS orderCount, u.forename, u.surname, g.title FROM users u LEFT JOIN orders o ON o.uid = u.id AND o.date > :date LEFT JOIN groups g ON u.group = g.id ORDER BY u.email', $qb->build());
}

public function testWhereNot() {
Expand Down Expand Up @@ -103,6 +102,28 @@ public function testGroup() {

$this->assertEquals('SELECT p.id, p.forename FROM people p GROUP BY p.forename ORDER BY p.id', $qb->build());
}

public function testJoinAlias()
{
$qb = new QueryBuilder();
$qb->from('activity_tracker', 'a', 'dw')->fields('*');
$qb->groupBy('id');
$qb->join('activity_types', 't', 'dw')->onEq('a.type', 't.id')->fields(['title', 'type_fk_description']);
$qb->orderBy('id DESC');

$sql = 'SELECT a.*, t.title AS type_fk_description FROM dw.activity_tracker a LEFT JOIN dw.activity_types t ON a.type = t.id GROUP BY a.id ORDER BY a.id DESC';
$this->assertEquals($sql, $qb->build());
}

public function testAutoAlias() {
$qb = new QueryBuilder();
$qb->from('foo')->fields('username');
$qb->join('fffoobar')->onEq('f.username', 'o.id')->fields('password');

$sql = 'SELECT f.username, o.password FROM foo f LEFT JOIN fffoobar o ON f.username = o.id ORDER BY f.username';
$this->assertEquals($sql, $qb->build());
}
}


?>

0 comments on commit 4ce6c53

Please sign in to comment.