J4 Issue ?
avatar joeforjoomla
joeforjoomla
11 Jul 2017

Steps to reproduce the issue

Maybe related to #17073 due to the usage of the Framework Database package.

Execute a query.

Call \Joomla\Database\DatabaseDriver->getAffectedRows()

Expected result

The number of affected rows

Actual result

Always -1

System information (as much as possible)

`
$db = \Joomla\CMS\Factory::getDbo();
$queryObject = $db->getQuery(true);
$queryObject->select('*');
$queryObject->from('#__content');
$limitStart = 0;
$limit = 5;
$db->setQuery ( $queryObject, $limitStart, $limit );

	$records = $db->loadObjectList();
	
	var_dump($db->getAffectedRows());

`
RETURNS -1 instead of 5

Using a getNumRows doesn't work as well, returning a NULL value because the cursor has already been cleaned

Additional comments

avatar joeforjoomla joeforjoomla - open - 11 Jul 2017
avatar joomla-cms-bot joomla-cms-bot - change - 11 Jul 2017
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1 for direct SQL query string
REGRESSION [4.0] - getAffectedRows always return -1
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1 for direct SQL query string
REGRESSION [4.0] - getAffectedRows always return -1
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
The description was changed
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
The description was changed
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar alikon
alikon - comment - 11 Jul 2017

you should use getNumRows() if you have issued a SELECT statement

avatar franz-wohlkoenig franz-wohlkoenig - change - 11 Jul 2017
Category SQL
avatar joeforjoomla
joeforjoomla - comment - 11 Jul 2017

This has always worked in the Joomla database layer using a SELECT statement and getAffectedRows

By the way getNumRows still doesn't work, always returning NULL

`
$db = \Joomla\CMS\Factory::getDbo();
$queryObject = $db->getQuery(true);
$queryObject->select('*');
$queryObject->from('#__content');
$limitStart = 0;
$limit = 5;
$db->setQuery ( $queryObject, $limitStart, $limit );

	$records = $db->loadObjectList();
	
	var_dump($db->getNumRows());

`
RETURNS NULL

avatar joeforjoomla
joeforjoomla - comment - 11 Jul 2017

@alikon the loadObjectList method includes the line:

$this->freeResult($cursor);

This makes impossible to use a getNumRows as well after executing a SELECT statement.

Freeing the $cursor after the execution of the loadObjectList prevents the usage of both getAffectedRows and getNumRows

avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1
REGRESSION [4.0] - getAffectedRows always return -1 because of freeResult in loadObjectList
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1
REGRESSION [4.0] - getAffectedRows always return -1 because of freeResult in loadObjectList
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
The description was changed
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1 because of freeResult in loadObjectList
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows always return -1 because of freeResult in loadObjectList
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList and other methods
avatar joeforjoomla joeforjoomla - edited - 11 Jul 2017
avatar joeforjoomla joeforjoomla - change - 11 Jul 2017
Title
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList
REGRESSION [4.0] - getAffectedRows/getNumRows always return -1/NULL because of freeResult in loadObjectList and other methods
avatar franz-wohlkoenig franz-wohlkoenig - change - 12 Jul 2017
Status New Discussion
avatar alikon
alikon - comment - 13 Jul 2017

ummh.... didn't tested yet on 4.0 but this snippet works as expected on 3.7.x and should work on 4.0 too

$db = JFactory::getDbo();	
$queryObject = $db->getQuery(true);
$queryObject->select('*');
$queryObject->from('#__content');
$limitStart = 0;
$limit = 5;
$db->setQuery ( $queryObject, $limitStart, $limit );
$db->execute();
$records = $db->getNumRows();
var_dump($records );

it returns int(5) as expected
@joeforjoomla can you confirm the correct behaviuor on 4.0 ?

avatar joeforjoomla
joeforjoomla - comment - 13 Jul 2017

@alikon the problem is not the 'execute' method... your snippet works as expected even on 4.0 but not anymore other methods used to retrieve records such as 'loadObjectList' and 'getAffectedRows'. 'getNumRows' didn't work on 3.7/3.8 too

The following fails on 4.0, while working on 3.7/3.8:

$db = \Joomla\CMS\Factory::getDbo();
$queryObject = $db->getQuery(true);
$queryObject->select('*');
$queryObject->from('#__content');
$limitStart = 0;
$limit = 5;
$db->setQuery ( $queryObject, $limitStart, $limit );
$records = $db->loadObjectList();
$numRecords = $db->getAffectedRows();
var_dump($numRecords );

3.7/3.8 -> 5
4.0 -> NULL

avatar joeforjoomla
joeforjoomla - comment - 13 Jul 2017

The problem looks like in the 'freeResult' method. In 4.0 the query is based on the statement and the 'freeResult' close the prepared statement, thus making impossible to retrieve the number of affected rows.

protected function freeResult($cursor = null)
	{
		$this->executed = false;

		if ($cursor instanceof \mysqli_result)
		{
			$cursor->free_result();
		}

		if ($this->prepared instanceof \mysqli_stmt)
		{
			$this->prepared->close();
			$this->prepared = null;
		}
	}

It works on 4.0 removing the following part:

	if ($this->prepared instanceof \mysqli_stmt)
		{
			$this->prepared->close();
			$this->prepared = null;
		}

Notice that mysqli_affected_rows is executed on the connection, mysqli_num_rows is executed on the cursor. Thus if the 'freeResult' clear the cursor but not the connection only mysqli_affected_rows can be executed after a SELECT using loadObjectList or similar methods.
In J4.0 even this option is lost.

avatar alikon
alikon - comment - 13 Jul 2017

let me disagree,
if you need to know the number of rows only then you don't need to "load an object list" for that
furthermore
if you have already retrieved data with $db->loadObjectList(); then you already know the number of rows returned by yuor query
so you don't need to call the db server again with a $db->getAffectedRows();
therefore freeResult() is doing well imo

avatar joeforjoomla
joeforjoomla - comment - 13 Jul 2017

Well, i want to get a result set using loadObjectList and i want to know how many records are in the set.
I know that i could simply use:

count($results);

but the point is that before J4.0 it was possible to get the elements count even calling a getAffectedRows after a loadObjectList.

avatar brianteeman brianteeman - change - 25 Mar 2018
Labels Added: J4 Issue
avatar brianteeman brianteeman - labeled - 25 Mar 2018
avatar mbabker
mbabker - comment - 24 Jul 2018

The database API (especially the MySQLi driver) has gone through a lot of refactoring since this was opened and the state of the API at the time is in no way comparable to where it's at today. So I'm going to close this for now since at this point it'd be pretty difficult to judge if the issue is still relevant or one that can be patched (if decided it needs to be). If decided it really still is an issue, please log an issue against https://github.com/joomla-framework/database (and even better if you can include a PHPUnit test case since the standalone package is doing a more thorough set of tests than what the test suites in this repo are covering).

avatar mbabker mbabker - close - 24 Jul 2018
avatar mbabker mbabker - change - 24 Jul 2018
Status Discussion Closed
Closed_Date 0000-00-00 00:00:00 2018-07-24 16:07:47
Closed_By mbabker

Add a Comment

Login with GitHub to post a comment