Skip to content

Commit

Permalink
Implemented 'having' and 'or_having' methods
Browse files Browse the repository at this point in the history
  • Loading branch information
timw4mail committed Apr 17, 2012
1 parent 052a155 commit bf16232
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `having`, `or_having`, `insert_batch` or `update_batch` 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 `insert_batch` or `update_batch` methods.

#### Retrieving Results

Expand Down
66 changes: 60 additions & 6 deletions classes/query_builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class Query_Builder {
// 'string' => 'k=?'
// )
private $query_map;

// Map for having clause
private $having_map;

// Convenience property for connection management
public $conn_name = "";
Expand Down Expand Up @@ -493,7 +496,28 @@ public function or_not_like($field, $val, $pos='both')
*/
public function having($key, $val=array())
{
// @todo Implement having
$where = $this->_where($key, $val);

// Create key/value placeholders
foreach($where as $f => $val)
{
// Split each key by spaces, in case there
// is an operator such as >, <, !=, etc.
$f_array = explode(' ', trim($f));

$item = $this->quote_ident($f_array[0]);

// Simple key value, or an operator
$item .= (count($f_array) === 1) ? '= ?' : " {$f_array[1]} ?";

// Put in the query map for select statements
$this->having_map[] = array(
'conjunction' => ( ! empty($this->having_map)) ? ' AND ' : ' HAVING ',
'string' => $item
);
}

return $this;
}

// --------------------------------------------------------------------------
Expand All @@ -507,15 +531,36 @@ public function having($key, $val=array())
*/
public function or_having($key, $val=array())
{
// @todo Implement or_having
$where = $this->_where($key, $val);

// Create key/value placeholders
foreach($where as $f => $val)
{
// Split each key by spaces, in case there
// is an operator such as >, <, !=, etc.
$f_array = explode(' ', trim($f));

$item = $this->quote_ident($f_array[0]);

// Simple key value, or an operator
$item .= (count($f_array) === 1) ? '= ?' : " {$f_array[1]} ?";

// Put in the query map for select statements
$this->having_map[] = array(
'conjunction' => ( ! empty($this->having_map)) ? ' OR ' : ' HAVING ',
'string' => $item
);
}

return $this;
}

// --------------------------------------------------------------------------
// ! 'Where' methods
// --------------------------------------------------------------------------

/**
* Do all the repeditive stuff for where type methods
* Do all the repeditive stuff for where/having type methods
*
* @param mixed $key
* @param mixed $val
Expand Down Expand Up @@ -569,7 +614,7 @@ public function where($key, $val=array())
$item = $this->quote_ident($f_array[0]);

// Simple key value, or an operator
$item .= (count($f_array === 1)) ? '= ?' : " {$f_array[1]} ?";
$item .= (count($f_array) === 1) ? '= ?' : " {$f_array[1]} ?";

// Put in the query map for select statements
$this->query_map[] = array(
Expand Down Expand Up @@ -997,7 +1042,7 @@ public function get($table='', $limit=FALSE, $offset=FALSE)
$sql = $this->_compile();

// Do prepared statements for anything involving a "where" clause
if ( ! empty($this->query_map))
if ( ! empty($this->query_map) || ! empty($this->having_map))
{
$result = $this->prepare_execute($sql, $this->values);
}
Expand Down Expand Up @@ -1218,7 +1263,7 @@ private function _reset()
$this->$name = NULL;
}

// Set values as an empty array
// Set empty arrays
$this->values = array();

// Set select string as an empty string, for proper handling
Expand Down Expand Up @@ -1266,6 +1311,15 @@ private function _compile($type='', $table="")
{
$sql .= $this->group_string;
}

// Set the having string
if ( ! empty($this->having_map))
{
foreach($this->having_map as $h)
{
$sql .= $h['conjunction'] . $h['string'];
}
}

// Set the order_by string
if ( ! empty($this->order_string))
Expand Down
28 changes: 28 additions & 0 deletions tests/core/db_qb_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,34 @@ function TestGetWhere()
$this->assertIsA($query, 'PDOStatement');
}

function TestHaving()
{
if (empty($this->db)) return;

$query = $this->db->select('id')
->from('create_test')
->group_by('id')
->having(array('id >' => 1))
->having('id !=', 3)
->get();

$this->assertIsA($query, 'PDOStatement');
}

function TestOrHaving()
{
if (empty($this->db)) return;

$query = $this->db->select('id')
->from('create_test')
->group_by('id')
->having(array('id >' => 1))
->or_having('id !=', 3)
->get();

$this->assertIsA($query, 'PDOStatement');
}

function TestGetViews()
{
if (empty($this->db)) return;
Expand Down
28 changes: 28 additions & 0 deletions tests/databases/firebird/firebird-qb.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,34 @@ function TestGetLimitSkip()
$this->assertIsA($query, 'Firebird_Result');
}

function TestHaving()
{
if (empty($this->db)) return;

$query = $this->db->select('id')
->from('create_test')
->group_by('id')
->having(array('id >' => 1))
->having('id !=', 3)
->get();

$this->assertIsA($query, 'Firebird_Result');
}

function TestOrHaving()
{
if (empty($this->db)) return;

$query = $this->db->select('id')
->from('create_test')
->group_by('id')
->having(array('id >' => 1))
->or_having('id !=', 3)
->get();

$this->assertIsA($query, 'Firebird_Result');
}

function TestSelectWhereGet()
{
$query = $this->db->select('id, key as k, val')
Expand Down
Binary file modified tests/db_files/FB_TEST_DB.FDB
Binary file not shown.

0 comments on commit bf16232

Please sign in to comment.