mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 14:18:52 +00:00
fix postcount resync for situations where low and high post ids are higher than step value, resulting in users having 0 posts. (Bug #38195)
Enforce a requirement for some DBMS (Oracle, PostgreSQL, MSSQL) where the table order is quite important in some situations. ;) Since this does not affect the operation of the other DBMS the code is placed into dbal.php. git-svn-id: file:///svn/phpbb/trunk@9176 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
parent
a0c9705bb7
commit
a39e879300
3 changed files with 76 additions and 12 deletions
|
@ -184,12 +184,36 @@ class acp_main
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resync post counts
|
// Resync post counts
|
||||||
$start = 0;
|
$start = $max_post_id = 0;
|
||||||
$step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000;
|
|
||||||
|
|
||||||
|
// Find the maximum post ID, we can only stop the cycle when we've reached it
|
||||||
|
$sql = 'SELECT MAX(forum_last_post_id) as max_post_id
|
||||||
|
FROM ' . FORUMS_TABLE;
|
||||||
|
$result = $db->sql_query($sql);
|
||||||
|
$max_post_id = (int) $db->sql_fetchfield('max_post_id');
|
||||||
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
|
// No maximum post id? :o
|
||||||
|
if (!$max_post_id)
|
||||||
|
{
|
||||||
|
$sql = 'SELECT MAX(post_id)
|
||||||
|
FROM ' . POSTS_TABLE;
|
||||||
|
$result = $db->sql_query($sql);
|
||||||
|
$max_post_id = (int) $db->sql_fetchfield('max_post_id');
|
||||||
|
$db->sql_freeresult($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still no maximum post id? Then we are finished
|
||||||
|
if (!$max_post_id)
|
||||||
|
{
|
||||||
|
add_log('admin', 'LOG_RESYNC_POSTCOUNTS');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000;
|
||||||
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_posts = 0');
|
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_posts = 0');
|
||||||
|
|
||||||
do
|
while ($start < $max_post_id)
|
||||||
{
|
{
|
||||||
$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
|
$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
|
||||||
FROM ' . POSTS_TABLE . '
|
FROM ' . POSTS_TABLE . '
|
||||||
|
@ -206,16 +230,11 @@ class acp_main
|
||||||
$db->sql_query($sql);
|
$db->sql_query($sql);
|
||||||
}
|
}
|
||||||
while ($row = $db->sql_fetchrow($result));
|
while ($row = $db->sql_fetchrow($result));
|
||||||
|
|
||||||
$start += $step;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$start = 0;
|
|
||||||
}
|
}
|
||||||
$db->sql_freeresult($result);
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
|
$start += $step;
|
||||||
}
|
}
|
||||||
while ($start);
|
|
||||||
|
|
||||||
add_log('admin', 'LOG_RESYNC_POSTCOUNTS');
|
add_log('admin', 'LOG_RESYNC_POSTCOUNTS');
|
||||||
|
|
||||||
|
|
|
@ -503,7 +503,8 @@ class dbal
|
||||||
|
|
||||||
$sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM ';
|
$sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM ';
|
||||||
|
|
||||||
$table_array = array();
|
// Build table array. We also build an alias array for later checks.
|
||||||
|
$table_array = $aliases = array();
|
||||||
foreach ($array['FROM'] as $table_name => $alias)
|
foreach ($array['FROM'] as $table_name => $alias)
|
||||||
{
|
{
|
||||||
if (is_array($alias))
|
if (is_array($alias))
|
||||||
|
@ -511,14 +512,58 @@ class dbal
|
||||||
foreach ($alias as $multi_alias)
|
foreach ($alias as $multi_alias)
|
||||||
{
|
{
|
||||||
$table_array[] = $table_name . ' ' . $multi_alias;
|
$table_array[] = $table_name . ' ' . $multi_alias;
|
||||||
|
$aliases[] = $multi_alias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$table_array[] = $table_name . ' ' . $alias;
|
$table_array[] = $table_name . ' ' . $alias;
|
||||||
|
$aliases[] = $alias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We run the following code to determine if we need to re-order the table array. ;)
|
||||||
|
// The reason for this is that for multiple tables in the FROM statement the last table need to match the first LEFT JOIN'ed table.
|
||||||
|
// DBMS who rely on this (at the moment i only spotted it on multi-aliases): Oracle, PostgreSQL and MSSQL
|
||||||
|
$first_join_match = false;
|
||||||
|
|
||||||
|
if (!empty($array['LEFT_JOIN']) && sizeof($array['FROM']) > 1)
|
||||||
|
{
|
||||||
|
// Take first LEFT JOIN
|
||||||
|
$join = current($array['LEFT_JOIN']);
|
||||||
|
|
||||||
|
// Determine the table used there (even if there are more than one used, we only want to have one
|
||||||
|
preg_match('/(' . implode('|', $aliases) . ')\.[^\s]+/U', str_replace(array('(', ')', 'AND', 'OR', ' '), '', $join['ON']), $matches);
|
||||||
|
|
||||||
|
if (!empty($matches[1]))
|
||||||
|
{
|
||||||
|
$first_join_match = trim($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a first join match, we need to make sure the table order is correct
|
||||||
|
if ($first_join_match !== false)
|
||||||
|
{
|
||||||
|
$table_array = $last = array();
|
||||||
|
|
||||||
|
foreach ($array['FROM'] as $table_name => $alias)
|
||||||
|
{
|
||||||
|
if (is_array($alias))
|
||||||
|
{
|
||||||
|
foreach ($alias as $multi_alias)
|
||||||
|
{
|
||||||
|
($multi_alias === $first_join_match) ? $last[] = $table_name . ' ' . $multi_alias : $table_array[] = $table_name . ' ' . $multi_alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
($alias === $first_join_match) ? $last[] = $table_name . ' ' . $alias : $table_array[] = $table_name . ' ' . $alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table_array = array_merge($table_array, $last);
|
||||||
|
}
|
||||||
|
|
||||||
$sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array));
|
$sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array));
|
||||||
|
|
||||||
if (!empty($array['LEFT_JOIN']))
|
if (!empty($array['LEFT_JOIN']))
|
||||||
|
|
Loading…
Add table
Reference in a new issue