Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend QueryBuilder for possibility to use "into" and "from" with sta… #6114

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 45 additions & 27 deletions src/Query/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

use function array_key_exists;
use function array_keys;
use function array_map;
use function array_unshift;
use function array_values;
use function count;
use function func_get_args;
use function func_num_args;
Expand Down Expand Up @@ -69,7 +71,6 @@ class QueryBuilder
'distinct' => false,
'from' => [],
'join' => [],
'set' => [],
'where' => null,
'groupBy' => [],
'having' => null,
Expand Down Expand Up @@ -585,7 +586,7 @@ public function getMaxResults()
/**
* Either appends to or replaces a single, generic query part.
*
* The available parts are: 'select', 'from', 'set', 'where',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for this change? What happens to existing apps that call $qb->add('set', …)?

* The available parts are: 'select', 'from', 'where',
* 'groupBy', 'having' and 'orderBy'.
*
* @param string $sqlPartName
Expand All @@ -610,7 +611,6 @@ public function add($sqlPartName, $sqlPart, $append = false)
$sqlPartName === 'orderBy'
|| $sqlPartName === 'groupBy'
|| $sqlPartName === 'select'
|| $sqlPartName === 'set'
) {
foreach ($sqlPart as $part) {
$this->sqlParts[$sqlPartName][] = $part;
Expand Down Expand Up @@ -755,10 +755,9 @@ public function delete($delete = null, $alias = null)
return $this;
}

return $this->add('from', [
'table' => $delete,
'alias' => $alias,
]);
$this->sqlParts['from'] = [['table' => $delete, 'alias' => $alias]];

return $this;
}

/**
Expand All @@ -777,18 +776,13 @@ public function delete($delete = null, $alias = null)
*
* @return $this This QueryBuilder instance.
*/
public function update($update = null, $alias = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apps that currently calls $qb->update() without parameters will break after your change.

public function update($update, $alias = null)
{
$this->type = self::UPDATE;

if ($update === null) {
return $this;
}
$this->sqlParts['from'] = [['table' => $update, 'alias' => $alias]];

return $this->add('from', [
'table' => $update,
'alias' => $alias,
]);
return $this;
}

/**
Expand Down Expand Up @@ -818,7 +812,28 @@ public function insert($insert = null)
return $this;
}

return $this->add('from', ['table' => $insert]);
$this->sqlParts['from'] = [['table' => $insert]];

return $this;
}

/**
* Turns the query being built into an insert query that inserts into
* a certain table
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->insert()
* ->into('users')
* </code>
*
* @param string $insert The table into which the rows should be inserted.
*
* @return $this This QueryBuilder instance.
*/
public function into($insert)
{
return $this->insert($insert);
}

/**
Expand All @@ -838,10 +853,9 @@ public function insert($insert = null)
*/
public function from($from, $alias = null)
{
return $this->add('from', [
'table' => $from,
'alias' => $alias,
], true);
Comment on lines -841 to -844
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for not calling add() anymore?

$this->sqlParts['from'][] = ['table' => $from, 'alias' => $alias];

return $this;
}

/**
Expand Down Expand Up @@ -970,7 +984,7 @@ public function rightJoin($fromAlias, $join, $alias, $condition = null)
*/
public function set($key, $value)
{
return $this->add('set', $key . ' = ' . $value, true);
return $this->setValue($key, $value);
}

/**
Expand Down Expand Up @@ -1423,7 +1437,7 @@ private function isLimitQuery(): bool
*/
private function getSQLForInsert(): string
{
return 'INSERT INTO ' . $this->sqlParts['from']['table'] .
return 'INSERT INTO ' . $this->sqlParts['from'][0]['table'] .
' (' . implode(', ', array_keys($this->sqlParts['values'])) . ')' .
' VALUES(' . implode(', ', $this->sqlParts['values']) . ')';
}
Expand All @@ -1433,11 +1447,15 @@ private function getSQLForInsert(): string
*/
private function getSQLForUpdate(): string
{
$table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
$table = $this->sqlParts['from'][0]['table']
. ($this->sqlParts['from'][0]['alias'] ? ' ' . $this->sqlParts['from'][0]['alias'] : '');

return 'UPDATE ' . $table
. ' SET ' . implode(', ', $this->sqlParts['set'])
. ' SET ' . implode(', ', array_map(
(static fn ($k, $v) => $k . ' = ' . $v),
array_keys($this->sqlParts['values']),
array_values($this->sqlParts['values']),
))
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
}

Expand All @@ -1446,8 +1464,8 @@ private function getSQLForUpdate(): string
*/
private function getSQLForDelete(): string
{
$table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
$table = $this->sqlParts['from'][0]['table']
. ($this->sqlParts['from'][0]['alias'] ? ' ' . $this->sqlParts['from'][0]['alias'] : '');

return 'DELETE FROM ' . $table
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
Expand Down
27 changes: 26 additions & 1 deletion tests/Query/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ public function testUpdateWhere(): void
public function testEmptyUpdate(): void
{
$qb = new QueryBuilder($this->conn);
$qb2 = $qb->update();
$qb2 = $qb->update('users');

self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
self::assertSame($qb2, $qb);
Expand Down Expand Up @@ -484,6 +484,17 @@ public function testEmptyDelete(): void
self::assertSame($qb2, $qb);
}

public function testEmptyDeleteUsingFrom(): void
{
$qb = new QueryBuilder($this->conn);
$qb->delete()
->from('users', 'u')
->from('articles')
->where('u.foo = ?');

self::assertEquals('DELETE FROM users u WHERE u.foo = ?', (string) $qb);
}

public function testInsertValues(): void
{
$qb = new QueryBuilder($this->conn);
Expand Down Expand Up @@ -554,6 +565,20 @@ public function testEmptyInsert(): void
self::assertSame($qb2, $qb);
}

public function testEmptyInsertUsingInto(): void
{
$qb = new QueryBuilder($this->conn);
$qb->insert()
->into('users')
->values(
['foo' => '?'],
)
->setValue('bar', '?');

self::assertEquals(QueryBuilder::INSERT, $qb->getType());
self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
}

public function testGetConnection(): void
{
$qb = new QueryBuilder($this->conn);
Expand Down