Skip to content

Commit

Permalink
Merge pull request #256 from envms/tests/where-changes
Browse files Browse the repository at this point in the history
Additional support for named parameters and improved where functionality
  • Loading branch information
cbornhoft committed Sep 28, 2018
2 parents 9800ab3 + 16988c4 commit 5c6fdc5
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 40 deletions.
31 changes: 8 additions & 23 deletions src/Queries/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,29 +326,14 @@ protected function buildQuery()

foreach ($this->clauses as $clause => $separator) {
if ($this->clauseNotEmpty($clause)) {
if ($clause === 'WHERE') {
$firstStatement = array_shift($this->statements[$clause]);
$query .= " {$clause} {$firstStatement[1]}"; // append first statement to WHERE without condition

if (!empty($this->statements[$clause])) {
foreach ($this->statements[$clause] as $statement) {
$query .= " {$statement[0]} {$statement[1]}";
}
}

// put the first statement back onto the beginning of the array in case we want to run this again
array_unshift($this->statements[$clause], $firstStatement);
}
else {
if (is_string($separator)) {
$query .= " {$clause} " . implode($separator, $this->statements[$clause]);
} elseif ($separator === null) {
$query .= " {$clause} {$this->statements[$clause]}";
} elseif (is_callable($separator)) {
$query .= call_user_func($separator);
} else {
throw new \Exception("Clause '$clause' is incorrectly set to '$separator'.");
}
if (is_string($separator)) {
$query .= " {$clause} " . implode($separator, $this->statements[$clause]);
} elseif ($separator === null) {
$query .= " {$clause} {$this->statements[$clause]}";
} elseif (is_callable($separator)) {
$query .= call_user_func($separator);
} else {
throw new \Exception("Clause '$clause' is incorrectly set to '$separator'.");
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/Queries/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,25 @@ protected function getClauseJoin()
return implode(' ', $this->statements['JOIN']);
}

/**
* @return string
*/
protected function getClauseWhere() {
$firstStatement = array_shift($this->statements['WHERE']);
$query = " WHERE {$firstStatement[1]}"; // append first statement to WHERE without condition

if (!empty($this->statements['WHERE'])) {
foreach ($this->statements['WHERE'] as $statement) {
$query .= " {$statement[0]} {$statement[1]}"; // [0] -> AND/OR [1] -> field = ?
}
}

// put the first statement back onto the beginning of the array in case we want to run this again
array_unshift($this->statements['WHERE'], $firstStatement);

return $query;
}

/**
* Statement can contain more tables (e.g. "table1.table2:table3:")
*
Expand Down
2 changes: 1 addition & 1 deletion src/Queries/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function __construct(Query $fluent, string $table)
'DELETE' => [$this, 'getClauseDelete'],
'FROM' => null,
'JOIN' => [$this, 'getClauseJoin'],
'WHERE' => ' AND ',
'WHERE' => [$this, 'getClauseWhere'],
'ORDER BY' => ', ',
'LIMIT' => null,
];
Expand Down
2 changes: 1 addition & 1 deletion src/Queries/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function __construct(Query $fluent, $from)
'SELECT' => ', ',
'FROM' => null,
'JOIN' => [$this, 'getClauseJoin'],
'WHERE' => ' AND ',
'WHERE' => [$this, 'getClauseWhere'],
'GROUP BY' => ',',
'HAVING' => ' AND ',
'ORDER BY' => ', ',
Expand Down
17 changes: 14 additions & 3 deletions src/Queries/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(Query $fluent, string $table)
'UPDATE' => [$this, 'getClauseUpdate'],
'JOIN' => [$this, 'getClauseJoin'],
'SET' => [$this, 'getClauseSet'],
'WHERE' => ' AND ',
'WHERE' => [$this, 'getClauseWhere'],
'ORDER BY' => ', ',
'LIMIT' => null,
];
Expand All @@ -42,11 +42,14 @@ public function __construct(Query $fluent, string $table)
}

/**
* In Update's case, parameters are not assigned until the query is built, since this method
*
* @param string|array $fieldOrArray
* @param bool|string $value
*
* @return $this
* @throws \Exception
*
* @return $this
*/
public function set($fieldOrArray, $value = false)
{
Expand All @@ -73,6 +76,8 @@ public function set($fieldOrArray, $value = false)
*
* @param boolean $getResultAsPdoStatement true to return the pdo statement instead of row count
*
* @throws \Exception
*
* @return int|boolean|\PDOStatement
*/
public function execute($getResultAsPdoStatement = false)
Expand Down Expand Up @@ -103,7 +108,13 @@ protected function getClauseSet()
{
$setArray = [];
foreach ($this->statements['SET'] as $field => $value) {
if ($value instanceof Literal) {
// named params are being used here
if (is_array($value) && strpos(key($value), ':') === 0) {
$key = key($value);
$setArray[] = $field . ' = ' . $key;
$this->parameters['SET'][$key] = $value[$key];
}
elseif ($value instanceof Literal) {
$setArray[] = $field . ' = ' . $value;
} else {
$setArray[] = $field . ' = ?';
Expand Down
27 changes: 25 additions & 2 deletions tests/Queries/SelectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ public function testWhereArrayParameter()
'type' => 'author'
]);

self::assertEquals([0 => 2, 1 => 'author'], $query->getParameters());
self::assertEquals('SELECT user.* FROM user WHERE id = ? AND type = ?', $query->getQuery(false));
self::assertEquals([0 => 2, 1 => 'author'], $query->getParameters());
}

public function testWhereColumnValue()
{
$query = $this->fluent->from('user')
->where('type', 'author');

self::assertEquals([0 => 'author'], $query->getParameters());
self::assertEquals('SELECT user.* FROM user WHERE type = ?', $query->getQuery(false));
self::assertEquals([0 => 'author'], $query->getParameters());
}

public function testWhereColumnNull()
Expand All @@ -118,6 +118,16 @@ public function testWhereColumnArray()
self::assertEquals([], $query->getParameters());
}

public function testWherePreparedArray()
{
$query = $this->fluent
->from('user')
->where('id IN (?, ?, ?)', [1, 2, 3]);

self::assertEquals('SELECT user.* FROM user WHERE id IN (?, ?, ?)', $query->getQuery(false));
self::assertEquals([0 => 1, 1 => 2, 2 => 3], $query->getParameters());
}

public function testWhereColumnName()
{
$query = $this->fluent->from('user')
Expand All @@ -134,6 +144,17 @@ public function testWhereColumnName()
self::assertEquals('Robert', $returnValue);
}

public function testWhereOr()
{
$query = $this->fluent->from('comment')
->where('comment.id = :id', [':id' => 1])
->whereOr('user.id = :userId', [':userId' => 2]);

self::assertEquals('SELECT comment.* FROM comment LEFT JOIN user ON user.id = comment.user_id WHERE comment.id = :id OR user.id = :userId',
$query->getQuery(false));
self::assertEquals([':id' => '1', ':userId' => '2'], $query->getParameters());
}

public function testWhereReset()
{
$query = $this->fluent->from('user')->where('id > ?', 0)->orderBy('name');
Expand All @@ -144,6 +165,8 @@ public function testWhereReset()
self::assertEquals(['id' => '1', 'country_id' => '1', 'type' => 'admin', 'name' => 'Marek'], $query->fetch());
}



public function testSelectArrayParam()
{
$query = $this->fluent
Expand Down
32 changes: 22 additions & 10 deletions tests/Queries/UpdateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function testUpdateFromArray()
$query = $this->fluent->update('user')->set(['name' => 'keraM', '`type`' => 'author'])->where('id', 1);

self::assertEquals('UPDATE user SET name = ?, `type` = ? WHERE id = ?', $query->getQuery(false));
self::assertEquals(['0' => 'keraM', '1' => 'author', '2' => '1'], $query->getParameters());
self::assertEquals([0 => 'keraM', 1 => 'author', 2 => '1'], $query->getParameters());
}

public function testUpdateLeftJoin()
Expand All @@ -67,7 +67,7 @@ public function testUpdateLeftJoin()

self::assertEquals('UPDATE user OUTER JOIN country ON country.id = user.country_id SET name = ?, `type` = ? WHERE id = ?',
$query->getQuery(false));
self::assertEquals(['0' => 'keraM', '1' => 'author', '2' => '1'], $query->getParameters());
self::assertEquals([0 => 'keraM', 1 => 'author', 2 => '1'], $query->getParameters());
}

public function testUpdateSmartJoin()
Expand All @@ -78,7 +78,7 @@ public function testUpdateSmartJoin()

self::assertEquals('UPDATE user LEFT JOIN country ON country.id = user.country_id SET type = ? WHERE country.id = ?',
$query->getQuery(false));
self::assertEquals(['0' => 'author', '1' => '1'], $query->getParameters());
self::assertEquals([0 => 'author', 1 => '1'], $query->getParameters());
}

public function testUpdateOrderLimit()
Expand All @@ -90,29 +90,29 @@ public function testUpdateOrderLimit()
->limit(1);

self::assertEquals('UPDATE user SET type = ? WHERE id = ? ORDER BY name LIMIT 1', $query->getQuery(false));
self::assertEquals(['0' => 'author', '1' => '2'], $query->getParameters());
self::assertEquals([0 => 'author', 1 => '2'], $query->getParameters());
}

public function testUpdateShortCut()
{
$query = $this->fluent->update('user', ['type' => 'admin'], 1);

self::assertEquals('UPDATE user SET type = ? WHERE id = ?', $query->getQuery(false));
self::assertEquals(['0' => 'admin', '1' => '1'], $query->getParameters());
self::assertEquals([0 => 'admin', 1 => '1'], $query->getParameters());
}

public function testUpdateZero()
{
$this->fluent->update('article')->set('content', '')->where('id', 1)->execute();
$user = $this->fluent->from('article')->where('id', 1)->fetch();

$printQuery = 'ID: ' . $user['id'] . ' - content: ' . $user['content'];
$printQuery = "ID: {$user['id']} - content: {$user['content']}";

$this->fluent->update('article')->set('content', 'content 1')->where('id', 1)->execute();

$user2 = $this->fluent->from('article')->where('id', 1)->fetch();

$printQuery2 = 'ID: ' . $user2['id'] . ' - content: ' . $user2['content'];
$printQuery2 = "ID: {$user2['id']} - content: {$user2['content']}";

self::assertEquals('ID: 1 - content: ', $printQuery);
self::assertEquals('ID: 1 - content: content 1', $printQuery2);
Expand All @@ -132,9 +132,21 @@ public function testUpdateWhere()

self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = ? WHERE `country`.`name` = ? AND `users`.`name` = ?',
$query->getQuery(false));
self::assertEquals(['0' => '1', '1' => 'Slovakia', '2' => 'Marek'], $query->getParameters());
self::assertEquals([0 => '1', 1 => 'Slovakia', 2 => 'Marek'], $query->getParameters());
self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET [users].[active] = ? WHERE [country].[name] = ? AND [users].[name] = ?',
$query2->getQuery(false));
self::assertEquals(['0' => '1', '1' => 'Slovakia', '2' => 'Marek'], $query2->getParameters());
self::assertEquals([0 => '1', 1 => 'Slovakia', 2 => 'Marek'], $query2->getParameters());
}
}

public function testUpdateNamedParameters()
{
$query = $this->fluent->update('users')
->set("`users`.`active`", [':active' => 1])
->where("`country`.`name` = :country", [':country' => 'Slovakia']);

self::assertEquals('UPDATE users LEFT JOIN country ON country.id = users.country_id SET `users`.`active` = :active WHERE `country`.`name` = :country',
$query->getQuery(false));
self::assertEquals([':active' => '1', ':country' => 'Slovakia'], $query->getParameters());
}

}

0 comments on commit 5c6fdc5

Please sign in to comment.