From 9b9ea5aeed4a1212591ec151dc410ed2a58a7349 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Fri, 13 Apr 2012 16:50:05 -0400 Subject: [PATCH] Added 'distinct' method to query builder --- README.md | 2 +- classes/db_reg.php | 10 ++++ classes/db_sql.php | 2 +- classes/query_builder.php | 35 +++++++++++--- tests/core/{parent.php => db_qb_test.php} | 53 +++++----------------- tests/core/db_test.php | 52 +++++++++++++++++++++ tests/databases/firebird/firebird-qb.php | 11 +++++ tests/db_files/FB_TEST_DB.FDB | Bin 802816 -> 802816 bytes tests/index.php | 7 ++- 9 files changed, 120 insertions(+), 52 deletions(-) rename tests/core/{parent.php => db_qb_test.php} (88%) create mode 100644 tests/core/db_test.php diff --git a/README.md b/README.md index 83d31af..1b15ca9 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Create a connection array or object similar to this: The parameters required depend on the database. ### Running Queries -Query uses the same interface as CodeIgniter's [Active Record class](http://codeigniter.com/user_guide/database/active_record.html). However, it does not implement the `count_all_results`, `distinct`, `having`, `or_having`, `insert_batch`, `update_batch`, or `count_all` methods. +Query uses the same interface as CodeIgniter's [Active Record class](http://codeigniter.com/user_guide/database/active_record.html). However, it does not implement the `count_all_results`, `having`, `or_having`, `insert_batch`, `update_batch`, or `count_all` methods. #### Retrieving Results diff --git a/classes/db_reg.php b/classes/db_reg.php index 8456370..c055563 100644 --- a/classes/db_reg.php +++ b/classes/db_reg.php @@ -54,6 +54,16 @@ class DB_Reg { // Set the current key in the registry self::$instance[$key] = new Query_Builder($db_params); } + + // -------------------------------------------------------------------------- + + /** + * Cleanup method + */ + public function __destruct() + { + unset(self::$instance); + } // -------------------------------------------------------------------------- diff --git a/classes/db_sql.php b/classes/db_sql.php index 45b6a60..30ea1e8 100644 --- a/classes/db_sql.php +++ b/classes/db_sql.php @@ -52,7 +52,7 @@ abstract class DB_SQL { */ public function distinct() { - return ' DISTINCT'; + return ' DISTINCT '; } // -------------------------------------------------------------------------- diff --git a/classes/query_builder.php b/classes/query_builder.php index cb92099..4cbb18a 100644 --- a/classes/query_builder.php +++ b/classes/query_builder.php @@ -19,7 +19,7 @@ class Query_Builder { // Compiled query component strings - private $select_string, + private $select_string = '', $from_string, $set_string, $order_string, @@ -171,7 +171,7 @@ class Query_Builder { } } - $this->select_string = implode(', ', $safe_array); + $this->select_string .= implode(', ', $safe_array); unset($safe_array); @@ -197,7 +197,7 @@ class Query_Builder { : $field; // Create the select string - $this->select_string = $this->sql->max()."({$field}) AS {$as} "; + $this->select_string .= $this->sql->max()."({$field}) AS {$as} "; return $this; } @@ -221,7 +221,7 @@ class Query_Builder { : $field; // Create the select string - $this->select_string = $this->sql->min()."({$field}) AS {$as} "; + $this->select_string .= $this->sql->min()."({$field}) AS {$as} "; return $this; } @@ -245,7 +245,7 @@ class Query_Builder { : $field; // Create the select string - $this->select_string = $this->sql->avg()."({$field}) AS {$as} "; + $this->select_string .= $this->sql->avg()."({$field}) AS {$as} "; return $this; } @@ -269,11 +269,26 @@ class Query_Builder { : $field; // Create the select string - $this->select_string = $this->sql->sum()."({$field}) AS {$as} "; + $this->select_string .= $this->sql->sum()."({$field}) AS {$as} "; return $this; } + // -------------------------------------------------------------------------- + + /** + * Adds the 'distinct' keyword to a query + * + * @return $this + */ + public function distinct() + { + // Prepend the keyword to the select string + $this->select_string = $this->sql->distinct() . $this->select_string; + + return $this; + } + // -------------------------------------------------------------------------- /** @@ -1119,11 +1134,15 @@ class Query_Builder { // Nothing query-generation related is safe! if ( ! is_callable($this->$name)) { - unset($this->$name); + $this->$name = NULL; } // Set values as an empty array $this->values = array(); + + // Set select string as an empty string, for proper handling + // of the 'distinct' keyword + $this->select_string = ''; } } @@ -1215,6 +1234,8 @@ class Query_Builder { break; } + + // echo $sql . '
'; return $sql; } diff --git a/tests/core/parent.php b/tests/core/db_qb_test.php similarity index 88% rename from tests/core/parent.php rename to tests/core/db_qb_test.php index d0e2f3c..2f8c5e0 100644 --- a/tests/core/parent.php +++ b/tests/core/db_qb_test.php @@ -12,46 +12,6 @@ // -------------------------------------------------------------------------- -/** - * Parent Database Test Class - */ -abstract class DBTest extends UnitTestCase { - - abstract function TestConnection(); - - function tearDown() - { - $this->db = NULL; - } - - function TestGetTables() - { - if (empty($this->db)) return; - - $tables = $this->db->get_tables(); - $this->assertTrue(is_array($tables)); - } - - function TestGetSystemTables() - { - if (empty($this->db)) return; - - $tables = $this->db->get_system_tables(); - - $this->assertTrue(is_array($tables)); - } - - function TestCreateTransaction() - { - if (empty($this->db)) return; - - $res = $this->db->beginTransaction(); - $this->assertTrue($res); - } -} - -// -------------------------------------------------------------------------- - /** * Query builder parent test class */ @@ -147,6 +107,17 @@ abstract class QBTest extends UnitTestCase { $this->assertIsA($query, 'PDOStatement'); } + function TestSelectDistinct() + { + if (empty($this->db)) return; + + $query = $this->db->select_sum('id', 'di') + ->distinct() + ->get('create_test'); + + $this->assertIsA($query, 'PDOStatement'); + } + function TestGetWhere() { if (empty($this->db)) return; @@ -319,4 +290,4 @@ abstract class QBTest extends UnitTestCase { } } -// End of parent.php \ No newline at end of file +// End of db_qb_test.php \ No newline at end of file diff --git a/tests/core/db_test.php b/tests/core/db_test.php new file mode 100644 index 0000000..3e698c2 --- /dev/null +++ b/tests/core/db_test.php @@ -0,0 +1,52 @@ +db = NULL; + } + + function TestGetTables() + { + if (empty($this->db)) return; + + $tables = $this->db->get_tables(); + $this->assertTrue(is_array($tables)); + } + + function TestGetSystemTables() + { + if (empty($this->db)) return; + + $tables = $this->db->get_system_tables(); + + $this->assertTrue(is_array($tables)); + } + + function TestCreateTransaction() + { + if (empty($this->db)) return; + + $res = $this->db->beginTransaction(); + $this->assertTrue($res); + } +} +// End of db_test.php \ No newline at end of file diff --git a/tests/databases/firebird/firebird-qb.php b/tests/databases/firebird/firebird-qb.php index 2c1f2f8..ee3bb86 100644 --- a/tests/databases/firebird/firebird-qb.php +++ b/tests/databases/firebird/firebird-qb.php @@ -116,6 +116,17 @@ class FirebirdQBTest extends QBTest { $this->assertIsA($query, 'Firebird_Result'); } + function TestSelectDistinct() + { + if (empty($this->db)) return; + + $query = $this->db->select_sum('id', 'di') + ->distinct() + ->get('create_test'); + + $this->assertIsA($query, 'Firebird_Result'); + } + function TestGetWhere() { if (empty($this->db)) return; diff --git a/tests/db_files/FB_TEST_DB.FDB b/tests/db_files/FB_TEST_DB.FDB index 9ec6109fc6bc833f7b8cf5b709adf5ea063a40f5..607f1a4c9d5fbcfdedc3c6c3cf2f4c6f4d326354 100755 GIT binary patch delta 1403 zcmZuxO=weD6h8MQG3`5zy{Q(eOf_ku^{<*>%HV3uROv!d2c+xHV9|vbX@!Cy4PCsA z8%5!uvzW~|vvJ{!KOGHKq-fC~MT!on3!A1@TW#FwCg?fu=9(_NkN58VZqE6>bI!dd z`FuK`PajaQE46k#)Q84=poV0gZU=bIFMy+de*tj#$EnU_n=#Pf@YC-D#oy`n>+$}7 zn@6>$m8Ts~2Rt40bjZ^yJRSCQgQpvBX*a0V|6`$;dnSBgw+@eucDln2Udp|d!r--$ zt0BW}zkR9&ZZvIzWF!X1nl``gd*p2myz-x_=W?ZHu6?|!+RR+yZ-(;My@SG0e@!69!U09& z6>O!oWo%U$N|kZ7nxye1+@~JVFN>Jk!$FI$V>qe~q%$@Vo4LiDxo>N+cq-_I3Hqmk zopiEg?!fQX1`=YZ>1?XBClUeI7byJ*|#lHN}fkBI{d||m9SD`?yb1YY&fjO2d7`exD zELSkOt(oWC#wk0GJ#p)7N|Vl5Y;x^pvMcjAPIoHUMyKCkh8`~A&-C#Px^%gWZDTEO z(Q%^EK62GoO2~ZZ)Bep-ntB(oOHEU#gekhRfU9_Y={3d`(#r+hjN(@t^hXJ^>KUbH za2Q%8aL$MU2XjM1JD<||GM`k(2kgjNUV8`@n=4e;ZSfDS-dlbzF;~&V5v9LB zU{^v~(~j>qNjD8kor>RXW~7blDi>Y;Ie6|1aT5;ZeuCn%3;RSaQatfn&XPOQVU1OB zupPp4I#Z;^3bs3G(@~A~uOdLv3T};BXp-Z86p0;cd@_!F8JTG}zmnldRaE`1O#Jl` G4}AswQ!;)4 delta 1258 zcmZ9LOK1~O6o${uYmyvmuYFOWElt|A)uK(Xt+)^g6NR?PZDH5&HSVb37HzEiwT}Ym7Nm{FPp)R7Hxs%&QC(LC2nLFqI?tjmX#Uim- z%Z!q95c+Ye?E+^CpYi9?b7;s zN;JZvCj?F2P8jv|f!7y;MIYaL>)@LagzLU8IL!ASj4pU&^g)>QAnO?G2fiSjHbSb@ zb59+tdV1`#;%CLewa(f@fF$QvY!*pcC}E(bu2MV34Uz{7piB{)FsUL@U(@jdM#T)B zEMteuS+R=bF%Y#zyx{>3{zhCFf2TDo<*fDgs!mkLTOQ)lAxO|nh9Md%fXq=nyb3}x zL;Yd`QIR7(MknEw~ zOY1!YP1QnKT0xPS$Gu|8_WqQ|9=>PWVHzlKdQ+C|0KLd!n|Mgymlcii@#D6)6lp7Q%5PdRQ+dFK*O`94LLa3rA1*ttgr zwYDP|;DnKrK=%9@(HqfmyHb!+(I}QM?6=&O)R-CM7YauMHA%2t@Vpc

hmFfc(%3~{(00q~0L3BkGI4^+Kc2Zl8noxJF>d^7=eMwD_Tw{Wy zCfHbGf~1PUDL^$|zxSWrBXuRcH|TN>yZM{V#_{P9f+FkK&%0}~fPs1m`nlRQB=Xor ct~_>fuUma@SX)K#Ca@;#Fe>Rk>nKkA1sKpQBLDyZ diff --git a/tests/index.php b/tests/index.php index abd4ff0..c1af0fa 100644 --- a/tests/index.php +++ b/tests/index.php @@ -24,10 +24,13 @@ define('DS', DIRECTORY_SEPARATOR); require_once('simpletest/autorun.php'); // Include db classes -require_once(BASE_DIR.'autoload.php'); +require_once(BASE_DIR . 'autoload.php'); // Require base testing classes -array_map('do_include', glob(TEST_DIR . "/core/*.php")); +require_once(TEST_DIR . '/core/core.php'); +require_once(TEST_DIR . '/core/settings.php'); +require_once(TEST_DIR . '/core/db_test.php'); +require_once(TEST_DIR . '/core/db_qb_test.php'); // Include db tests // Load db classes based on capability