diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php index 73edb3381e77..d7991e9190a4 100644 --- a/system/Database/BaseResult.php +++ b/system/Database/BaseResult.php @@ -61,11 +61,11 @@ abstract class BaseResult implements ResultInterface public $currentRow = 0; /** - * Number of rows + * The number of records in the query result * - * @var integer + * @var integer|null */ - public $numRows; + protected $numRows = null; /** * Row data @@ -130,7 +130,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) { return []; } @@ -197,7 +197,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) { return []; } @@ -240,7 +240,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) { return []; } @@ -532,6 +532,31 @@ public function getUnbufferedRow(string $type = 'object') //-------------------------------------------------------------------- + /** + * Number of rows in the result set; checks for previous count, falls + * back on counting resultArray or resultObject, finally fetching resultArray + * if nothing was previously fetched + * + * @return integer + */ + public function getNumRows(): int + { + if (is_int($this->numRows)) + { + return $this->numRows; + } + if ($this->resultArray !== []) + { + return $this->numRows = count($this->resultArray); + } + if ($this->resultObject !== []) + { + return $this->numRows = count($this->resultObject); + } + + return $this->numRows = count($this->getResultArray()); + } + /** * Gets the number of fields in the result set. * diff --git a/system/Database/MySQLi/Result.php b/system/Database/MySQLi/Result.php index 656fb6c4dbad..6ceb92347022 100644 --- a/system/Database/MySQLi/Result.php +++ b/system/Database/MySQLi/Result.php @@ -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; @@ -175,4 +175,21 @@ 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 + */ + public function getNumRows(): int + { + if (! is_int($this->numRows)) + { + $this->numRows = $this->resultID->num_rows; + } + + return $this->numRows; + } + + //-------------------------------------------------------------------- } diff --git a/system/Database/Postgre/Result.php b/system/Database/Postgre/Result.php index 1040c4ac4069..3f0dbc574006 100644 --- a/system/Database/Postgre/Result.php +++ b/system/Database/Postgre/Result.php @@ -140,5 +140,21 @@ 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 + */ + public function getNumRows(): int + { + if (! is_int($this->numRows)) + { + $this->numRows = pg_num_rows($this->resultID); + } + + return $this->numRows; + } + //-------------------------------------------------------------------- } diff --git a/system/Database/SQLSRV/Result.php b/system/Database/SQLSRV/Result.php index ad254efcc9b2..500a6593e675 100755 --- a/system/Database/SQLSRV/Result.php +++ b/system/Database/SQLSRV/Result.php @@ -181,4 +181,22 @@ 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 + */ + public function getNumRows(): int + { + if (! is_int($this->numRows)) + { + $this->numRows = sqlsrv_num_rows($this->resultID); + } + + return $this->numRows; + } + + //-------------------------------------------------------------------- } diff --git a/system/Test/Mock/MockResult.php b/system/Test/Mock/MockResult.php index 4e9cef1eb63b..3d2d0d39d1b5 100644 --- a/system/Test/Mock/MockResult.php +++ b/system/Test/Mock/MockResult.php @@ -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; + } + + //-------------------------------------------------------------------- } diff --git a/tests/system/Database/Live/GetNumRowsTest.php b/tests/system/Database/Live/GetNumRowsTest.php new file mode 100644 index 000000000000..1fcfdb849bc0 --- /dev/null +++ b/tests/system/Database/Live/GetNumRowsTest.php @@ -0,0 +1,42 @@ +db->table('job')->get(); + $this->assertEquals(4, $query->getNumRows()); + } + +} diff --git a/user_guide_src/source/database/results.rst b/user_guide_src/source/database/results.rst index 8e9fdc426157..dc8bdc94ccd4 100644 --- a/user_guide_src/source/database/results.rst +++ b/user_guide_src/source/database/results.rst @@ -283,6 +283,19 @@ 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:: Because SQLite3 lacks an efficient method returning a record count, + CodeIgniter will fetch and buffer the query result records internally and + return a count of the resulting record array, which can be inefficient. + **freeResult()** It frees the memory associated with the result and deletes the result @@ -500,6 +513,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 + .. php:method:: freeResult() :rtype: void