diff options
author | Bharat Mediratta <bharat@menalto.com> | 2009-01-23 08:07:37 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2009-01-23 08:07:37 +0000 |
commit | cd6629ad23ba9468002d063483e9c49b59e200aa (patch) | |
tree | 6c9d54d25a89c7436b9b67d6da50b86f80f09d26 | |
parent | 6941af664f72e41eb4aa6e628200c78a77e069ab (diff) |
Add support for parenthetical grouping to Database queries. Turns out
that this is something they kind of want for Kohana :-)
Upstream ticket for this change: http://dev.kohanaphp.com/ticket/1070
-rw-r--r-- | core/libraries/MY_Database.php | 45 | ||||
-rw-r--r-- | core/libraries/MY_ORM.php | 30 | ||||
-rw-r--r-- | core/tests/Database_Test.php | 86 |
3 files changed, 161 insertions, 0 deletions
diff --git a/core/libraries/MY_Database.php b/core/libraries/MY_Database.php new file mode 100644 index 00000000..f5e412a6 --- /dev/null +++ b/core/libraries/MY_Database.php @@ -0,0 +1,45 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 Bharat Mediratta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ +class Database extends Database_Core { + public function open_paren() { + $this->where[] = "("; + return $this; + } + + public function close_paren() { + // Search backwards for the last opening paren and resolve it + $i = count($this->where) - 1; + $this->where[$i] .= ")"; + while (--$i >= 0) { + if ($this->where[$i] == "(") { + // Remove the paren from the where clauses, and add it to the right of the operator of the + // next where clause. If removing the paren makes the next where clause the first element + // in the where list, then the operator shouldn't be there. It's there because we + // calculate whether or not we need an operator based on the number of where clauses, and + // the open paren seems like a where clause even though it isn't. + array_splice($this->where, $i, 1); + $this->where[$i] = preg_replace("/^(AND|OR) /", $i ? "\\1 (" : "(", $this->where[$i]); + return $this; + } + } + + throw new Kohana_Database_Exception('database.missing_open_paren'); + } +}
\ No newline at end of file diff --git a/core/libraries/MY_ORM.php b/core/libraries/MY_ORM.php new file mode 100644 index 00000000..f0bca39b --- /dev/null +++ b/core/libraries/MY_ORM.php @@ -0,0 +1,30 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 Bharat Mediratta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ +class ORM extends ORM_Core { + public function open_paren() { + $this->db->open_paren(); + return $this; + } + + public function close_paren() { + $this->db->close_paren(); + return $this; + } +} diff --git a/core/tests/Database_Test.php b/core/tests/Database_Test.php new file mode 100644 index 00000000..0d4351c9 --- /dev/null +++ b/core/tests/Database_Test.php @@ -0,0 +1,86 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 Bharat Mediratta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ +class Database_Test extends Unit_Test_Case { + function simple_where_test() { + $sql = Database::instance() + ->where("a", 1) + ->where("b", 2) + ->compile(); + $sql = str_replace("\n", " ", $sql); + $this->assert_same("SELECT * WHERE `a` = 1 AND `b` = 2", $sql); + } + + function compound_where_test() { + $sql = Database::instance() + ->where("outer1", 1) + ->open_paren() + ->where("inner1", 1) + ->orwhere("inner2", 2) + ->close_paren() + ->where("outer2", 2) + ->compile(); + $sql = str_replace("\n", " ", $sql); + $this->assert_same( + "SELECT * WHERE `outer1` = 1 AND (`inner1` = 1 OR `inner2` = 2) AND `outer2` = 2", + $sql); + } + + function group_first_test() { + $sql = Database::instance() + ->open_paren() + ->where("inner1", 1) + ->orwhere("inner2", 2) + ->close_paren() + ->where("outer1", 1) + ->where("outer2", 2) + ->compile(); + $sql = str_replace("\n", " ", $sql); + $this->assert_same( + "SELECT * WHERE (`inner1` = 1 OR `inner2` = 2) AND `outer1` = 1 AND `outer2` = 2", + $sql); + } + + function where_array_test() { + $sql = Database::instance() + ->where("outer1", 1) + ->open_paren() + ->where("inner1", 1) + ->orwhere(array("inner2" => 2, "inner3" => 3)) + ->close_paren() + ->compile(); + $sql = str_replace("\n", " ", $sql); + $this->assert_same( + "SELECT * WHERE `outer1` = 1 AND (`inner1` = 1 OR `inner2` = 2 OR `inner3` = 3)", + $sql); + } + + function notlike_test() { + $sql = Database::instance() + ->where("outer1", 1) + ->open_paren() + ->ornotlike("inner1", 1) + ->close_paren() + ->compile(); + $sql = str_replace("\n", " ", $sql); + $this->assert_same( + "SELECT * WHERE `outer1` = 1 OR ( `inner1` NOT LIKE '%1%')", + $sql); + } +} |