From 8c597543e1d487cce9f8b3d8503c4470761c0f24 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 26 Nov 2022 00:54:49 +0100 Subject: [PATCH] Fix : use count() in lists - part 1 --- htdocs/adherents/list.php | 11 ++++++-- htdocs/asset/list.php | 26 +++++++++---------- htdocs/bookmarks/list.php | 8 ++++-- htdocs/comm/propal/list.php | 16 ++++++++++-- htdocs/commande/list.php | 16 ++++++++++-- htdocs/compta/bank/list.php | 21 +++++++++++++-- htdocs/contact/list.php | 17 ++++++++++-- htdocs/expedition/list.php | 17 ++++++++++-- htdocs/expensereport/list.php | 17 ++++++++++-- htdocs/fichinter/list.php | 13 +++++----- htdocs/holiday/list.php | 17 ++++++++++-- .../modulebuilder/template/myobject_list.php | 21 +++++---------- htdocs/product/list.php | 1 + htdocs/reception/list.php | 21 +++++++++++++-- htdocs/societe/list.php | 12 ++++----- htdocs/ticket/list.php | 17 +++++++++--- htdocs/user/list.php | 21 +++++---------- 17 files changed, 192 insertions(+), 80 deletions(-) diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 2e54ed03db8..60b47a54c7e 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -346,6 +346,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."adherent as d"; if (!empty($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (d.rowid = ef.fk_object)"; @@ -480,9 +483,13 @@ $sql .= $hookmanager->resPrint; // Count total nb of records with no order and no limits $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $resql = $db->query($sql); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); if ($resql) { - $nbtotalofrecords = $db->num_rows($resql); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; } else { dol_print_error($db); } diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index 5e00c2d2433..1ddfd2a1c82 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -216,6 +216,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; @@ -297,21 +300,18 @@ $sql .= !empty($hookmanager->resPrint) ? (" HAVING 1=1 " . $hookmanager->resPrin // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /* This old and fast method to get and count full list returns all record so use a high amount of memory. - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); - */ - /* The slow method does not consume memory on mysql (not tested on pgsql) */ - /*$resql = $db->query($sql, 0, 'auto', 1); - while ($db->fetch_object($resql)) { - $nbtotalofrecords++; - }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); - $objforcount = $db->fetch_object($resql); - $nbtotalofrecords = $objforcount->nbtotalofrecords; - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 5f8eb93af96..56aae3a15f7 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -105,6 +105,9 @@ llxHeader('', $title); $sql = "SELECT b.rowid, b.dateb, b.fk_user, b.url, b.target, b.title, b.favicon, b.position,"; $sql .= " u.login, u.lastname, u.firstname"; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."bookmark as b LEFT JOIN ".MAIN_DB_PREFIX."user as u ON b.fk_user=u.rowid"; $sql .= " WHERE 1=1"; $sql .= " AND b.entity IN (".getEntity('bookmark').")"; @@ -116,7 +119,8 @@ if (!$user->admin) { $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { $objforcount = $db->fetch_object($resql); @@ -125,7 +129,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index eb1791285c0..924d85c3781 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -585,6 +585,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql = preg_replace('/, $/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; @@ -796,13 +799,22 @@ $sql .= ', p.ref DESC'; // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 0ac8d109575..a093743b072 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -825,6 +825,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s2 ON s2.rowid = s.parent"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; @@ -1048,13 +1051,22 @@ $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index faf1c52a0c0..4a3735a15b2 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -195,6 +195,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as b"; if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (b.rowid = ef.fk_object)"; @@ -257,8 +260,22 @@ $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 062d041c81a..f65152286b7 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -392,6 +392,9 @@ if (isModEnabled('mailing')) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (p.rowid = ef.fk_object)"; @@ -634,12 +637,22 @@ if ($view == "recent") { // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 3b06f005787..c319e8f8b68 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -284,6 +284,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."expedition as e"; if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (e.rowid = ef.fk_object)"; @@ -450,12 +453,22 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index f1e6cf355db..814dc16d835 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -285,6 +285,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as d"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (d.rowid = ef.fk_object)"; @@ -345,12 +348,22 @@ $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 587089c2d35..5812cb2ba8f 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -251,6 +251,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f"; if (isModEnabled('project')) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as pr on f.fk_projet = pr.rowid"; @@ -324,20 +327,18 @@ $sql .= $hookmanager->resPrint; // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /* This old and fast method to get and count full list returns all record so use a high amount of memory. */ - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); /* The fast and low memory method to get and count full list converts the sql into a sql count */ - /*$sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { $objforcount = $db->fetch_object($resql); $nbtotalofrecords = $objforcount->nbtotalofrecords; } else { dol_print_error($db); - }*/ + } - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 85cc0961363..676ed15cd28 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -304,6 +304,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (cp.rowid = ef.fk_object)"; @@ -361,12 +364,22 @@ $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } $sql .= $db->plimit($limit + 1, $offset); diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index f26afd1a503..e5718ef7d7f 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -282,6 +282,9 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); //$sql .= ", COUNT(rc.rowid) as anotherfield"; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; //$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."anothertable as rc ON rc.parent = t.rowid"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { @@ -364,21 +367,9 @@ $sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPri // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /* This old and fast method to get and count full list returns all record so use a high amount of memory. - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); - */ - /* The slow method does not consume memory on mysql (not tested on pgsql) */ - /*$resql = $db->query($sql, 0, 'auto', 1); - while ($db->fetch_object($resql)) { - if (empty($nbtotalofrecords)) { - $nbtotalofrecords = 1; // We can't make +1 because init value is '' - } else { - $nbtotalofrecords++; - } - }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { $objforcount = $db->fetch_object($resql); @@ -387,7 +378,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 613d0a1c5d6..da17d702820 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -621,6 +621,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $page = 0; $offset = 0; } + $db->free($resql); } // Complete request and execute it with limit diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index 210f068af0a..000bb708998 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -531,6 +531,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."reception as e"; if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (e.rowid = ef.fk_object)"; @@ -614,8 +617,22 @@ $sql .= $hookmanager->resPrint; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); } $sql .= $db->order($sortfield, $sortorder); diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index f5fcc56b49d..6da7fcf3779 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -488,6 +488,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s2 ON s.parent = s2.rowid"; if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { @@ -723,14 +726,9 @@ $sql .= $hookmanager->resPrint; // Count total nb of records with no order and no limits $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /*$resql = $db->query($sql); - if ($resql) { - $nbtotalofrecords = $db->num_rows($resql); - } else { - dol_print_error($db); - }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { $objforcount = $db->fetch_object($resql); diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 8430598a308..4c4dce5a428 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -353,6 +353,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; @@ -458,11 +461,17 @@ $sql .= $hookmanager->resPrint; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); - $objforcount = $db->fetch_object($resql); - $nbtotalofrecords = $objforcount->nbtotalofrecords; - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } diff --git a/htdocs/user/list.php b/htdocs/user/list.php index d472ae3e9f4..8610113f0da 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -373,6 +373,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as u"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (u.rowid = ef.fk_object)"; @@ -481,21 +484,9 @@ $sql .= $hookmanager->resPrint; // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /* This old and fast method to get and count full list returns all record so use a high amount of memory. - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); - */ - /* The slow method does not consume memory on mysql (not tested on pgsql) */ - /*$resql = $db->query($sql, 0, 'auto', 1); - while ($db->fetch_object($resql)) { - if (empty($nbtotalofrecords)) { - $nbtotalofrecords = 1; // We can't make +1 because init value is '' - } else { - $nbtotalofrecords++; - } - }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { $objforcount = $db->fetch_object($resql); @@ -504,7 +495,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; }