Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Can't limit delete or update in the query builder. #66

Merged
merged 2 commits into from

2 participants

@nathggns
Owner

No description provided.

@nathggns
Owner

Need order support too.

@ClaudioAlbertin ClaudioAlbertin merged commit 54beead into development
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 21, 2013
  1. @nathggns

    Normalise.

    nathggns authored
  2. @nathggns
This page is out of date. Refresh to see the latest.
View
68 system/classes/database/query/builder.php
@@ -132,6 +132,8 @@ public function limit($start, $end = null) {
$part = [$start];
if (!is_null($end)) $part[] = $end;
+ if (!isset($this->query_opts['limit'])) $this->query_opts['limit'] = [];
+
$this->query_opts['limit'] = array_merge($this->query_opts['limit'], $part);
return $this;
@@ -153,9 +155,9 @@ public function set($key, $value) {
/* Utility functions for the subclass */
- protected function extract() {
+ protected function extract_select() {
- $options = call_user_func_array([$this, 'extract_shuffle'], func_get_args());
+ $options = call_user_func_array([$this, 'extract_shuffle_select'], func_get_args());
$args = [];
$required = ['table'];
@@ -189,7 +191,67 @@ protected function extract() {
return $args;
}
- protected function extract_shuffle($table = null, $options = []) {
+ protected function extract_update() {
+
+ $args = $this->extract_shuffle([
+ 'table'
+ ], [
+ 'table',
+ 'data',
+ 'where',
+ 'conds',
+ 'limit',
+ 'order'
+ ], func_get_args());
+
+ if (isset($args['conds'])) {
+ $args['where'] = $args['conds'];
+ unset($args['conds']);
+ }
+
+ return $args;
+ }
+
+ protected function extract_delete() {
+ $args = $this->extract_shuffle([
+ 'table'
+ ], [
+ 'table',
+ 'where',
+ 'conds',
+ 'limit',
+ 'order'
+ ], func_get_args());
+
+ if (isset($args['conds'])) {
+ $args['where'] = $args['conds'];
+ unset($args['conds']);
+ }
+
+ return $args;
+ }
+
+ protected function extract_shuffle($required, $keys, $options) {
+ if (count($options) === 1 && is_array(reset($options)) && is_hash(reset($options))) {
+ $args = reset($options);
+ } else {
+ $args = [];
+
+ foreach ($keys as $i => $key) {
+ $args[$key] = isset($options[$i]) ? $options[$i] : null;
+ }
+ }
+
+ foreach ($required as $req) {
+ if (!isset($args[$req])) {
+ throw new InvalidArgumentException('Missing ' . $req);
+ }
+ }
+
+ return $args;
+ }
+
+ protected function extract_shuffle_select($table = null, $options = []) {
// Argument shuffling
if (is_array($table)) {
$options = $table;
View
4 system/classes/database/query/builders/interface.php
@@ -8,7 +8,7 @@
interface DatabaseQueryBuilderInterface {
public function select();
public function insert($table, $data);
- public function update($table, $data, $where = []);
+ public function update();
public function structure($table);
- public function delete($table);
+ public function delete();
}
View
110 system/classes/database/query/builders/sql.php
@@ -7,37 +7,25 @@
*/
class DatabaseQueryBuilderSQL extends DatabaseQueryBuilder {
- protected $operators = ['=', '>', '<', '<>', '!='];
+ protected $operators = ['=', '>', '<', '<>', '!='];
protected $joins = ['AND', 'OR'];
protected $default_meta = ['connector' => 'AND', 'operator' => '='];
public function select() {
$args = func_get_args();
- $options = call_user_func_array([$this, 'extract'], $args);
+ $options = call_user_func_array([$this, 'extract_select'], $args);
- if ((count($args) === 1 && is_string(reset($args))) || $this->chained()) {
- return $this->start('select', recursive_overwrite($this->query_opts, $options));
+ if ($this->chained($args)) {
+ return $this->start('select', $options);
}
- $options = call_user_func_array([$this, 'extract'], $args);
extract($options);
if (!is_array($table)) {
$table = [$table];
}
- $parts = [];
- foreach ($table as $key => $val) {
- $col = $this->backtick(is_int($key) ? $val : $key);
-
- if (!is_int($key)) {
- $col .= ' AS ' . $this->backtick($val);
- }
-
- $parts[] = $col;
- }
-
- $table = implode(',', $parts);
+ $table = $this->table($table);
$vals = $this->backtick($vals);
@@ -110,84 +98,61 @@ public function insert($table, $data = null) {
return $query;
}
- public function update($table, $data = null, $where = null) {
-
- $default = [
- 'table' => null,
- 'data' => [],
- 'conds' => []
- ];
-
- $options = [];
-
- if (is_array($table)) {
- $options = $table;
- } else {
- $options['table'] = $table;
- }
+ public function update() {
- if (!is_null($data)) {
- $options['data'] = $data;
- }
+ $args = func_get_args();
+ $options = call_user_func_array([$this, 'extract_update'], $args);
- if (!is_null($where)) {
- $options['conds'] = $where;
+ if ($this->chained($args)) {
+ $this->start('update', $options);
+ return $this;
}
- $options = recursive_overwrite($default, $options);
- list($table, $data, $where) = array_values($options);
-
-
- if ($this->chained(func_get_args())) {
- return $this->start('update', $options);
- }
+ extract($options);
if (count($data) === 0) {
throw new InvalidArgumentException('You must pass data to set');
}
- $table = $this->backtick($table);
+ if (!is_array($table)) {
+ $table = [$table];
+ }
+
+ $table = $this->table($table);
$keys = $this->backtick(array_keys($data));
$data = $this->escape($data);
$query = 'UPDATE ' . $table . ' SET ' . $this->pairs($keys, $data);
if (count($where) > 0) $query .= ' ' . $this->where_array($where);
+ if (count($order) > 0) $query .= ' ' . $this->order_array($order);
+ if (count($limit) > 0) $query .= ' ' . $this->limit_array($limit);
$query .= ';';
return $query;
}
- public function delete($table, $where = null) {
+ public function delete() {
- $defaults = [
- 'table' => null,
- 'conds' => []
- ];
-
- $options = [];
-
- if (is_array($table)) {
- $options = $table;
- } else {
- $options['table'] = $table;
- }
+ $args = func_get_args();
+ $options = call_user_func_array([$this, 'extract_delete'], $args);
- if (!is_null($where)) {
- $options['conds'] = $where;
+ if ($this->chained($args)) {
+ return $this->start('delete', $options);
}
- $options = recursive_overwrite($defaults, $options);
- list($table, $where) = array_values($options);
+ extract($options);
- if ($this->chained(func_get_args())) {
- return $this->start('delete', $options);
+ if (!is_array($table)) {
+ $table = [$table];
}
- $table = $this->backtick($table);
+ $table = $this->table($table);
$query = 'DELETE FROM ' . $table;
if (count($where) > 0) $query .= ' ' . $this->where_array($where);
+ if (count($order) > 0) $query .= ' ' . $this->order_array($order);
+ if (count($limit) > 0) $query .= ' ' . $this->limit_array($limit);
$query .= ';';
@@ -437,4 +402,19 @@ protected function escape($value) {
return $value;
}
+
+ protected function table($table) {
+ $parts = [];
+ foreach ($table as $key => $val) {
+ $col = $this->backtick(is_int($key) ? $val : $key);
+
+ if (!is_int($key)) {
+ $col .= ' AS ' . $this->backtick($val);
+ }
+
+ $parts[] = $col;
+ }
+
+ return implode(',', $parts);
+ }
}
View
122 tests/DatabaseQueryBuilderSQLTest.php
@@ -288,6 +288,56 @@ public function testUpdate() {
$this->assertEquals('UPDATE `users` SET `name` = \'Bob\' WHERE `name` = \'Paul\';', $sql);
}
+ public function testUpdateWithLimit() {
+ $sql = $this->builder->update([
+ 'table' => 'users',
+ 'data' => [
+ 'name' => 'Bob'
+ ],
+ 'where' => [
+ 'name' => 'Paul'
+ ],
+ 'limit' => [23, 43]
+ ]);
+
+ $this->assertEquals('UPDATE `users` SET `name` = \'Bob\' WHERE `name` = \'Paul\' LIMIT 23, 43;', $sql);
+ }
+
+ public function testUpdateWithOrder() {
+ $sql = $this->builder->update([
+ 'table' => 'users',
+ 'data' => [
+ 'name' => 'Bob'
+ ],
+ 'where' => [
+ 'name' => 'Paul'
+ ],
+ 'order' => [
+ ['name', 'DESC']
+ ]
+ ]);
+
+ $this->assertEquals('UPDATE `users` SET `name` = \'Bob\' WHERE `name` = \'Paul\' ORDER BY `name` DESC;', $sql);
+ }
+
+ public function testUpdateWithOrderAndLimit() {
+ $sql = $this->builder->update([
+ 'table' => 'users',
+ 'data' => [
+ 'name' => 'Bob'
+ ],
+ 'where' => [
+ 'name' => 'Paul'
+ ],
+ 'order' => [
+ ['name', 'DESC']
+ ],
+ 'limit' => [23, 43]
+ ]);
+
+ $this->assertEquals('UPDATE `users` SET `name` = \'Bob\' WHERE `name` = \'Paul\' ORDER BY `name` DESC LIMIT 23, 43;', $sql);
+ }
+
public function testUpdateWithoutWhere() {
$sql = $this->builder->update('users', [
'name' => 'Bob'
@@ -320,6 +370,21 @@ public function testUpdateChained() {
$this->assertEquals('UPDATE `users` SET `name` = \'nat\' WHERE `name` = \'bob\';', $sql);
}
+ public function testUpdateChainedOrder() {
+ $sql = $this->builder->start()->update('users')->set('name', 'nat')->where('name', 'bob')->order('name', 'desc')->end();
+ $this->assertEquals('UPDATE `users` SET `name` = \'nat\' WHERE `name` = \'bob\' ORDER BY `name` DESC;', $sql);
+ }
+
+ public function testUpdateChainedLimit() {
+ $sql = $this->builder->start()->update('users')->set('name', 'nat')->where('name', 'bob')->limit(22, 56)->end();
+ $this->assertEquals('UPDATE `users` SET `name` = \'nat\' WHERE `name` = \'bob\' LIMIT 22, 56;', $sql);
+ }
+
+ public function testUpdateChainedOrderAndLimit() {
+ $sql = $this->builder->start()->update('users')->set('name', 'nat')->where('name', 'bob')->order('name', 'desc')->limit(22, 56)->end();
+ $this->assertEquals('UPDATE `users` SET `name` = \'nat\' WHERE `name` = \'bob\' ORDER BY `name` DESC LIMIT 22, 56;', $sql);
+ }
+
public function testUpdateChainedWithoutStart() {
$sql = $this->builder->update('users')->set('name', 'nat')->where('name', 'bob')->end();
$this->assertEquals('UPDATE `users` SET `name` = \'nat\' WHERE `name` = \'bob\';', $sql);
@@ -351,6 +416,48 @@ public function testDelete() {
$this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\';', $sql);
}
+ public function testDeleteWithOrder() {
+ $sql = $this->builder->delete([
+ 'table' => 'users',
+ 'where' => [
+ 'name' => 'Harry'
+ ],
+ 'order' => [
+ ['name', 'DESC']
+ ]
+ ]);
+
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' ORDER BY `name` DESC;', $sql);
+ }
+
+ public function testDeleteWithLimit() {
+ $sql = $this->builder->delete([
+ 'table' => 'users',
+ 'where' => [
+ 'name' => 'Harry'
+ ],
+ 'order' => [
+ ['name', 'DESC']
+ ],
+ 'limit' => [26, 50]
+ ]);
+
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' ORDER BY `name` DESC LIMIT 26, 50;', $sql);
+ }
+
+ public function testDeleteWithOrderAndLimit() {
+ $sql = $this->builder->delete([
+ 'table' => 'users',
+ 'where' => [
+ 'name' => 'Harry'
+ ],
+ 'limit' => [26, 50]
+ ]);
+
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' LIMIT 26, 50;', $sql);
+ }
+
+
public function testDeleteChained() {
$sql = $this->builder->start()->delete('users')->where('name', 'Harry')->end();
$this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\';', $sql);
@@ -361,6 +468,21 @@ public function testDeleteChainedWithoutStart() {
$this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\';', $sql);
}
+ public function testDeleteChainedWithOrder() {
+ $sql = $this->builder->start()->delete('users')->where('name', 'Harry')->order('name', 'desc')->end();
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' ORDER BY `name` DESC;', $sql);
+ }
+
+ public function testDeleteChainedWithLimit() {
+ $sql = $this->builder->start()->delete('users')->where('name', 'Harry')->limit(22, 30)->end();
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' LIMIT 22, 30;', $sql);
+ }
+
+ public function testDeleteChainedWithLimitAndOrder() {
+ $sql = $this->builder->start()->delete('users')->where('name', 'Harry')->order('name', 'desc')->limit(22, 30)->end();
+ $this->assertEquals('DELETE FROM `users` WHERE `name` = \'Harry\' ORDER BY `name` DESC LIMIT 22, 30;', $sql);
+ }
+
public function testDeleteWithComplexWhere() {
$sql = $this->builder->delete('users', [
'logins' => Database::where_gt(5)
Something went wrong with that request. Please try again.