Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds BaseResult::getNumRows(). adds getNumRows to various DBMS Result classes #4049

Merged
merged 11 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions system/Database/BaseResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,6 @@ abstract class BaseResult implements ResultInterface
*/
public $currentRow = 0;

/**
* Number of rows
*
* @var integer
*/
public $numRows;

/**
* Row data
*
Expand Down Expand Up @@ -130,7 +123,7 @@ public function getCustomResultObject(string $className)
return $this->customResultObject[$className];
}

if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0)
if (is_bool($this->resultID) || ! $this->resultID || $this->getNumRows() === 0)
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
{
return [];
}
Expand Down Expand Up @@ -197,7 +190,7 @@ public function getResultArray(): array
// In the event that query caching is on, the result_id variable
// will not be a valid resource so we'll simply return an empty
// array.
if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0)
if (is_bool($this->resultID) || ! $this->resultID || $this->getNumRows() === 0)
{
return [];
}
Expand Down Expand Up @@ -240,7 +233,7 @@ public function getResultObject(): array
// In the event that query caching is on, the result_id variable
// will not be a valid resource so we'll simply return an empty
// array.
if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0)
if (is_bool($this->resultID) || ! $this->resultID || $this->getNumRows() === 0)
{
return [];
}
Expand Down
14 changes: 13 additions & 1 deletion system/Database/MySQLi/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function getFieldData(): array
$retVal[$i] = new stdClass();
$retVal[$i]->name = $data->name;
$retVal[$i]->type = $data->type;
$retVal[$i]->type_name = in_array($data->type, [1, 247], true) ? 'char' : (isset($dataTypes[$data->type]) ? $dataTypes[$data->type] : null);
$retVal[$i]->type_name = in_array($data->type, [1, 247], true) ? 'char' : (isset($dataTypes[$data->type]) ? $dataTypes[$data->type] : null);
$retVal[$i]->max_length = $data->max_length;
$retVal[$i]->primary_key = (int) ($data->flags & 2);
$retVal[$i]->length = $data->length;
Expand Down Expand Up @@ -175,4 +175,16 @@ protected function fetchObject(string $className = 'stdClass')
}

//--------------------------------------------------------------------

/**
* Returns the number of rows in the resultID (i.e., mysqli_result object)
*
* @return integer number of rows in a query result; if the number of rows is greater than PHP_INT_MAX, this will cast the number as a string which will yield PHP_INT_MAX
michalsn marked this conversation as resolved.
Show resolved Hide resolved
*/
public function getNumRows() : int
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
{
return intval($this->resultID->num_rows);
}

//--------------------------------------------------------------------
}
19 changes: 19 additions & 0 deletions system/Database/Postgre/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

namespace CodeIgniter\Database\Postgre;

use CodeIgniter\Database\Exceptions\DatabaseException;
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
use CodeIgniter\Database\BaseResult;
use CodeIgniter\Entity;
use stdClass;
use CodeIgniter\Database\Exceptions\DataException;
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved

/**
* Result for Postgre
Expand Down Expand Up @@ -140,5 +142,22 @@ protected function fetchObject(string $className = 'stdClass')
return pg_fetch_object($this->resultID, null, $className);
}

//--------------------------------------------------------------------
/**
* Returns the number of rows in the resultID (i.e., PostgreSQL query result resource)
*
* @return integer The number of rows in the query result
* @throws DatabaseException if an error is encountered retrieving the row count
*/
public function getNumRows() : int
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
{
$retval = pg_num_rows($this->resultID);
if ($retval < 0)
{
throw new DatabaseException('An error was encountered retrieving the row count');
}
return intval($retval);
}

//--------------------------------------------------------------------
}
9 changes: 9 additions & 0 deletions system/Database/ResultInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,13 @@ public function freeResult();
public function dataSeek(int $n = 0);

//--------------------------------------------------------------------

/**
* Gets the number of rows returned in the result set.
*
* @return integer
*/
public function getNumRows(): int;

//--------------------------------------------------------------------
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
}
20 changes: 20 additions & 0 deletions system/Database/SQLSRV/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Database\SQLSRV;

use CodeIgniter\Database\Exceptions\DatabaseException;
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
use CodeIgniter\Database\BaseResult;
use CodeIgniter\Entity;
use stdClass;
Expand Down Expand Up @@ -181,4 +182,23 @@ protected function fetchObject(string $className = 'stdClass')
}
return sqlsrv_fetch_object($this->resultID, $className);
}

//--------------------------------------------------------------------
/**
* Returns the number of rows in the resultID (i.e., SQLSRV query result resource)
*
* @return integer Returns the number of rows retrieved on success
* @throws DatabaseException if an error is encountered attempting to retrieve the count (eg if the prior select query failed)
*/
public function getNumRows() : int
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
{
$retval = sqlsrv_num_rows($this->resultID);
if ($retval === false)
{
throw new DatabaseException('Error retrieving row count');
}
return intval($retval);
}

//--------------------------------------------------------------------
}
39 changes: 39 additions & 0 deletions system/Database/SQLite3/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Database\SQLite3;

use Exception;
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
use Closure;
use CodeIgniter\Database\BaseResult;
use CodeIgniter\Database\Exceptions\DatabaseException;
Expand All @@ -22,6 +23,14 @@
*/
class Result extends BaseResult
{

/**
* SQLite3 doesn't have a numRows method or property so we store brute-force counting here
*
* @var null|integer
*/
protected $numRows;

/**
* Gets the number of fields in the result set.
*
Expand Down Expand Up @@ -98,6 +107,7 @@ public function freeResult()
{
$this->resultID->finalize();
$this->resultID = false;
$this->numRows = null;
}
}

Expand Down Expand Up @@ -179,5 +189,34 @@ protected function fetchObject(string $className = 'stdClass')
return $classObj;
}

//--------------------------------------------------------------------
/**
* SQLite3Result class does not have a numRows function, so we have to brute force count results
* NOTE: brute force counting the results also resets the results, which might cause problems.
*
* @throws DatabaseException
*/
public function getNumRows() : int
{
if (! $this->resultID)
{
throw new DatabaseException(__METHOD__ . ' cannot run if there is no query result');
}
if (is_null($this->numRows))
{
// the rows have not been counted yet, count by brute force
$nrows = 0;
$this->resultID->reset();
while ($this->resultID->fetchArray(SQLITE3_NUM)) // SQLITE3_NUM should be slightly more efficient
{
$nrows++;
}
$this->resultID->reset();
$this->numRows = $nrows;
}

return $this->numRows;
}

//--------------------------------------------------------------------
}
12 changes: 12 additions & 0 deletions system/Test/Mock/MockResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,16 @@ protected function fetchObject($className = 'stdClass')
}

//--------------------------------------------------------------------

/**
* Gets the number of fields in the result set.
*
* @return integer
*/
public function getNumRows(): int
{
return 0;
}

//--------------------------------------------------------------------
}
42 changes: 42 additions & 0 deletions tests/system/Database/Live/GetNumRowsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php namespace Builder;

use CodeIgniter\Test\CIDatabaseTestCase;

class GetNumRowsTest extends CIDatabaseTestCase
{
protected $refresh = true;

protected $seed = 'Tests\Support\Database\Seeds\CITestSeeder';

/**
* Added as instructed at https://codeigniter4.github.io/userguide/testing/database.html#the-test-class
* {@inheritDoc}
*
* @see \CodeIgniter\Test\CIDatabaseTestCase::setUp()
*/
public function setUp(): void
{
parent::setUp();
}

/**
* Added as instructed at https://codeigniter4.github.io/userguide/testing/database.html#the-test-class
* {@inheritDoc}
*
* @see \CodeIgniter\Test\CIDatabaseTestCase::tearDown()
*/
public function tearDown(): void
{
parent::tearDown();
}

/**
* tests newly added ResultInterface::getNumRows with a live db
*/
public function testGetRowNum()
{
$query = $this->db->table('job')->get();
$this->assertEquals(4, $query->getNumRows());
}

}
22 changes: 22 additions & 0 deletions user_guide_src/source/database/results.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,21 @@ Make sure to call the method using your query result object::

echo $query->getFieldNames();

**getNumRows()**

The number of records returned by the query. Make sure to call
the method using your query result object::

$query = $db->query('SELECT * FROM my_table');

echo $query->getNumRows();

.. note:: PHP's SQLite3 module does not support this type of function and will
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved
throw an Exception. Use Builder->countAllResults() instead or return your results
into an array and count its elements. For other DBMS systems, this number may
return different values depending on whether you are buffering results or not.
Refer to the documentation of your chosen DBMS for more detail.

**freeResult()**

It frees the memory associated with the result and deletes the result
Expand Down Expand Up @@ -500,6 +515,13 @@ Class Reference
Generates an array of ``stdClass`` objects containing
field meta-data.

.. php:method:: getNumRows()

:returns: Number of rows in result set
:rtype: int

Returns number of rows returned by the query
sneakyimp marked this conversation as resolved.
Show resolved Hide resolved

.. php:method:: freeResult()

:rtype: void
Expand Down