Ch-ch-ch-changes

- Made us more DB independent by making many queries capability based instead of DB specific
- Finished PHP5ifying of the acm_file class, now with some (hopefully) enhancements to its performance
- Sped up viewforum considerably (also goes towards mcp_forum)

I really hope I didn't explode CVS...


git-svn-id: file:///svn/phpbb/trunk@8301 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
David M 2008-01-04 18:35:49 +00:00
parent edd6c34eda
commit af738dbc2a
23 changed files with 346 additions and 296 deletions

View file

@ -88,7 +88,7 @@ class acm
if ($fp = @fopen($this->cache_dir . 'data_global.' . $phpEx, 'wb')) if ($fp = @fopen($this->cache_dir . 'data_global.' . $phpEx, 'wb'))
{ {
@flock($fp, LOCK_EX); @flock($fp, LOCK_EX);
fwrite($fp, "<?php\n\$this->vars = " . var_export($this->vars, true) . ";\n\n\$this->var_expires = " . var_export($this->var_expires, true) . "\n?>"); fwrite($fp, "<?php\n\$this->vars = unserialize('" . serialize($this->vars) . "');\n\$this->var_expires = unserialize('" . serialize($this->var_expires) . "');");
@flock($fp, LOCK_UN); @flock($fp, LOCK_UN);
fclose($fp); fclose($fp);
@ -192,7 +192,7 @@ class acm
if ($fp = @fopen($this->cache_dir . "data{$var_name}.$phpEx", 'wb')) if ($fp = @fopen($this->cache_dir . "data{$var_name}.$phpEx", 'wb'))
{ {
@flock($fp, LOCK_EX); @flock($fp, LOCK_EX);
fwrite($fp, "<?php\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n\n\$data = " . var_export($var, true) . ";\n?>"); fwrite($fp, "<?php\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n\$data = " . (sizeof($var) ? "unserialize('" . serialize($var) . "');" : 'array();'));
@flock($fp, LOCK_UN); @flock($fp, LOCK_UN);
fclose($fp); fclose($fp);
@ -210,7 +210,7 @@ class acm
/** /**
* Purge cache data * Purge cache data
*/ */
function purge() public function purge()
{ {
// Purge all phpbb cache files // Purge all phpbb cache files
$dir = @opendir($this->cache_dir); $dir = @opendir($this->cache_dir);
@ -247,7 +247,7 @@ class acm
/** /**
* Destroy cache data * Destroy cache data
*/ */
function destroy($var_name, $table = '') public function destroy($var_name, $table = '')
{ {
global $phpEx; global $phpEx;
@ -327,7 +327,7 @@ class acm
/** /**
* Check if a given cache entry exist * Check if a given cache entry exist
*/ */
function _exists($var_name) private function _exists($var_name)
{ {
if ($var_name[0] === '_') if ($var_name[0] === '_')
{ {
@ -353,7 +353,7 @@ class acm
/** /**
* Load cached sql query * Load cached sql query
*/ */
function sql_load($query) public function sql_load($query)
{ {
global $phpEx; global $phpEx;
@ -386,7 +386,7 @@ class acm
/** /**
* Save sql query * Save sql query
*/ */
function sql_save($query, &$query_result, $ttl) public function sql_save($query, &$query_result, $ttl)
{ {
global $db, $phpEx; global $db, $phpEx;
@ -408,10 +408,10 @@ class acm
} }
$db->sql_freeresult($query_result); $db->sql_freeresult($query_result);
$file = "<?php\n\n/* " . str_replace('*/', '*\/', $query) . " */\n"; $file = "<?php\n/* " . str_replace('*/', '*\/', $query) . " */";
$file .= "\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n"; $file .= "\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n";
fwrite($fp, $file . "\n\$this->sql_rowset[\$query_id] = " . var_export($this->sql_rowset[$query_id], true) . ";\n?>"); fwrite($fp, $file . "\$this->sql_rowset[\$query_id] = " . (sizeof($this->sql_rowset[$query_id]) ? "unserialize('" . serialize($this->sql_rowset[$query_id]) . "');" : 'array();'));
@flock($fp, LOCK_UN); @flock($fp, LOCK_UN);
fclose($fp); fclose($fp);
@ -421,18 +421,10 @@ class acm
} }
} }
/**
* Ceck if a given sql query exist in cache
*/
function sql_exists($query_id)
{
return isset($this->sql_rowset[$query_id]);
}
/** /**
* Fetch row from cache (database) * Fetch row from cache (database)
*/ */
function sql_fetchrow($query_id) public function sql_fetchrow($query_id)
{ {
if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
{ {
@ -445,7 +437,7 @@ class acm
/** /**
* Fetch a field from the current row of a cached database result (database) * Fetch a field from the current row of a cached database result (database)
*/ */
function sql_fetchfield($query_id, $field) public function sql_fetchfield($query_id, $field)
{ {
if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id]))
{ {
@ -458,7 +450,7 @@ class acm
/** /**
* Seek a specific row in an a cached database result (database) * Seek a specific row in an a cached database result (database)
*/ */
function sql_rowseek($rownum, $query_id) public function sql_rowseek($rownum, $query_id)
{ {
if ($rownum >= sizeof($this->sql_rowset[$query_id])) if ($rownum >= sizeof($this->sql_rowset[$query_id]))
{ {
@ -472,7 +464,7 @@ class acm
/** /**
* Free memory used for a cached database result (database) * Free memory used for a cached database result (database)
*/ */
function sql_freeresult($query_id) public function sql_freeresult($query_id)
{ {
if (!isset($this->sql_rowset[$query_id])) if (!isset($this->sql_rowset[$query_id]))
{ {
@ -488,7 +480,7 @@ class acm
/** /**
* Removes/unlinks file * Removes/unlinks file
*/ */
function remove_file($filename) private function remove_file($filename)
{ {
if (!@unlink($filename)) if (!@unlink($filename))
{ {

View file

@ -477,16 +477,12 @@ class acp_icons
// The user has already selected a smilies_pak file // The user has already selected a smilies_pak file
if ($current == 'delete') if ($current == 'delete')
{ {
switch ($db->sql_layer) if ($db->truncate)
{ {
case 'sqlite': $db->sql_query('TRUNCATE TABLE ' . $table);
case 'firebird': else
$db->sql_query('DELETE FROM ' . $table); {
break; $db->sql_query('DELETE FROM ' . $table);
default:
$db->sql_query('TRUNCATE TABLE ' . $table);
break;
} }
switch ($mode) switch ($mode)

View file

@ -202,16 +202,12 @@ class acp_main
break; break;
case 'db_track': case 'db_track':
switch ($db->sql_layer) if ($db->truncate)
{ {
case 'sqlite': $db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
case 'firebird': else
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE); {
break; $db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
default:
$db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE);
break;
} }
// This can get really nasty... therefore we only do the last six months // This can get really nasty... therefore we only do the last six months

View file

@ -211,53 +211,22 @@ class acp_reasons
// Let the deletion be confirmed... // Let the deletion be confirmed...
if (confirm_box(true)) if (confirm_box(true))
{ {
$sql = 'SELECT reason_id $sql = 'SELECT reason_id, report_text
FROM ' . REPORTS_REASONS_TABLE . " FROM ' . REPORTS_REASONS_TABLE . "
WHERE LOWER(reason_title) = 'other'"; WHERE LOWER(reason_title) = 'other'";
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$other_reason_id = (int) $db->sql_fetchfield('reason_id'); $row = $db->sql_fetchrow($result);
$other_reason_id = (int) $row['reason_id'];
$report_text = $row['report_text'];
$db->sql_freeresult($result); $db->sql_freeresult($result);
switch ($db->sql_layer) $report_text .= $reason_row['reason_description'] . "\n\n";
{
// The ugly one!
case 'mysqli':
case 'mysql4':
case 'mysql':
// Change the reports using this reason to 'other'
$sql = 'UPDATE ' . REPORTS_TABLE . '
SET reason_id = ' . $other_reason_id . ", report_text = CONCAT('" . $db->sql_escape($reason_row['reason_description']) . "\n\n', report_text)
WHERE reason_id = $reason_id";
break;
// Standard? What's that? $sql = 'UPDATE ' . REPORTS_TABLE . '
case 'mssql': SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($report_text) "'
case 'mssql_odbc': WHERE reason_id = $reason_id";
// Change the reports using this reason to 'other'
$sql = "DECLARE @ptrval binary(16)
SELECT @ptrval = TEXTPTR(report_text)
FROM " . REPORTS_TABLE . "
WHERE reason_id = " . $reason_id . "
UPDATETEXT " . REPORTS_TABLE . ".report_text @ptrval 0 0 '" . $db->sql_escape($reason_row['reason_description']) . "\n\n'
UPDATE " . REPORTS_TABLE . '
SET reason_id = ' . $other_reason_id . "
WHERE reason_id = $reason_id";
break;
// Teh standard
case 'postgres':
case 'oracle':
case 'firebird':
case 'sqlite':
// Change the reports using this reason to 'other'
$sql = 'UPDATE ' . REPORTS_TABLE . '
SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text
WHERE reason_id = $reason_id";
break;
}
$db->sql_query($sql); $db->sql_query($sql);
$db->sql_query('DELETE FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id); $db->sql_query('DELETE FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id);

View file

@ -295,31 +295,10 @@ class cache
{ {
global $db; global $db;
switch ($db->sql_layer) $sql = 'SELECT user_id, bot_agent, bot_ip
{ FROM ' . BOTS_TABLE . '
case 'mssql': WHERE bot_active = 1
case 'mssql_odbc': ORDER BY ' . $db->sql_function('length_varchar', 'bot_agent') . 'DESC';
$sql = 'SELECT user_id, bot_agent, bot_ip
FROM ' . BOTS_TABLE . '
WHERE bot_active = 1
ORDER BY LEN(bot_agent) DESC';
break;
case 'firebird':
$sql = 'SELECT user_id, bot_agent, bot_ip
FROM ' . BOTS_TABLE . '
WHERE bot_active = 1
ORDER BY CHAR_LENGTH(bot_agent) DESC';
break;
// LENGTH supported by MySQL, IBM DB2 and Oracle for sure...
default:
$sql = 'SELECT user_id, bot_agent, bot_ip
FROM ' . BOTS_TABLE . '
WHERE bot_active = 1
ORDER BY LENGTH(bot_agent) DESC';
break;
}
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$bots = array(); $bots = array();

View file

@ -52,6 +52,15 @@ class dbal
// Supports multi inserts? // Supports multi inserts?
var $multi_insert = false; var $multi_insert = false;
// Supports COUNT(DISTINCT ...)?
var $count_distinct = true;
// Supports multiple table deletion
var $multi_table_deletion = false;
// Supports table truncation
var $truncate = true;
/** /**
* Current sql layer * Current sql layer
*/ */

View file

@ -28,6 +28,9 @@ class dbal_firebird extends dbal
var $last_query_text = ''; var $last_query_text = '';
var $service_handle = false; var $service_handle = false;
// can't truncate a table
var $truncate = false;
/** /**
* Connect to server * Connect to server
*/ */
@ -376,6 +379,20 @@ class dbal_firebird extends dbal
return str_replace("'", "''", $msg); return str_replace("'", "''", $msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'OCTET_LENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -308,6 +308,20 @@ class dbal_mssql extends dbal
return str_replace("'", "''", $msg); return str_replace("'", "''", $msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'DATALENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -336,6 +336,20 @@ class dbal_mssql_odbc extends dbal
return str_replace("'", "''", $msg); return str_replace("'", "''", $msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'DATALENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -32,6 +32,9 @@ class dbal_mysql extends dbal
var $mysql_version; var $mysql_version;
var $multi_insert = true; var $multi_insert = true;
// Supports multiple table deletion
var $multi_table_deletion = false;
/** /**
* Connect to server * Connect to server
* @access public * @access public
@ -301,6 +304,20 @@ class dbal_mysql extends dbal
return @mysql_real_escape_string($msg, $this->db_connect_id); return @mysql_real_escape_string($msg, $this->db_connect_id);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'LENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -28,6 +28,9 @@ class dbal_mysqli extends dbal
{ {
var $multi_insert = true; var $multi_insert = true;
// Supports multiple table deletion
var $multi_table_deletion = false;
/** /**
* Connect to server * Connect to server
*/ */
@ -270,6 +273,20 @@ class dbal_mysqli extends dbal
return @mysqli_real_escape_string($this->db_connect_id, $msg); return @mysqli_real_escape_string($this->db_connect_id, $msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'LENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -533,6 +533,23 @@ class dbal_oracle extends dbal
return str_replace("'", "''", $msg); return str_replace("'", "''", $msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
return 'LENGTH(' . $col . ')';
break;
case 'length_text':
return 'dbms_lob.getlength(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -84,9 +84,17 @@ class dbal_postgres extends dbal
// determine what version of PostgreSQL is running, we can be more efficient if they are running 8.2+ // determine what version of PostgreSQL is running, we can be more efficient if they are running 8.2+
$this->pgsql_version = @pg_parameter_status($this->db_connect_id, 'server_version'); $this->pgsql_version = @pg_parameter_status($this->db_connect_id, 'server_version');
if (!empty($this->pgsql_version) && $this->pgsql_version[0] >= '8' && $this->pgsql_version[2] >= '2') if (!empty($this->pgsql_version) && $this->pgsql_version[0] >= '8')
{ {
$this->multi_insert = true; if ($this->pgsql_version[2] >= '1')
{
$this->multi_table_deletion = true;
}
if ($this->pgsql_version[2] >= '2')
{
$this->multi_insert = true;
}
} }
if ($schema !== '') if ($schema !== '')
@ -331,6 +339,20 @@ class dbal_postgres extends dbal
return @pg_escape_string($msg); return @pg_escape_string($msg);
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'LENGTH(' . $col . ')';
break;
}
}
/** /**
* Build LIKE expression * Build LIKE expression
* @access private * @access private

View file

@ -25,6 +25,12 @@ include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
*/ */
class dbal_sqlite extends dbal class dbal_sqlite extends dbal
{ {
// like MS ACCESS, SQLite does not support COUNT(DISTINCT ...)
var $count_distinct = false;
// can't truncate a table
var $truncate = false;
/** /**
* Connect to server * Connect to server
*/ */
@ -257,6 +263,20 @@ class dbal_sqlite extends dbal
return 'GLOB \'' . $this->sql_escape($expression) . '\''; return 'GLOB \'' . $this->sql_escape($expression) . '\'';
} }
/**
* Expose a DBMS specific function
*/
function sql_function($type, $col)
{
switch ($type)
{
case 'length_varchar':
case 'length_text':
return 'LENGTH(' . $col . ')';
break;
}
}
/** /**
* return sql error array * return sql error array
* @access private * @access private

View file

@ -3007,7 +3007,15 @@ function page_header($page_title = '', $display_online_list = true)
// Get number of online guests // Get number of online guests
if (!$config['load_online_guests']) if (!$config['load_online_guests'])
{ {
if ($db->sql_layer === 'sqlite') if ($db->count_distinct)
{
$sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests
FROM ' . SESSIONS_TABLE . ' s
WHERE s.session_user_id = ' . ANONYMOUS . '
AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) .
$reading_sql;
}
else
{ {
$sql = 'SELECT COUNT(session_ip) as num_guests $sql = 'SELECT COUNT(session_ip) as num_guests
FROM ( FROM (
@ -3018,14 +3026,6 @@ function page_header($page_title = '', $display_online_list = true)
$reading_sql . $reading_sql .
')'; ')';
} }
else
{
$sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests
FROM ' . SESSIONS_TABLE . ' s
WHERE s.session_user_id = ' . ANONYMOUS . '
AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) .
$reading_sql;
}
$result = $db->sql_query($sql); $result = $db->sql_query($sql);
$guests_online = (int) $db->sql_fetchfield('num_guests'); $guests_online = (int) $db->sql_fetchfield('num_guests');
$db->sql_freeresult($result); $db->sql_freeresult($result);

View file

@ -1004,40 +1004,38 @@ function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true)
{ {
$where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : ''); $where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : '');
switch ($db->sql_layer) if ($db->multi_table_deletion)
{ {
case 'mysql4': $sql = 'DELETE FROM ' . TOPICS_TABLE . ' t
case 'mysqli': USING ' . TOPICS_TABLE . ' t2
$sql = 'DELETE t.*
FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
WHERE t.topic_moved_id = t2.topic_id WHERE t.topic_moved_id = t2.topic_id
AND t.topic_time < ' . (time() - $max_age) AND t.topic_time < ' . (time() - $max_age)
. $where; . $where;
$db->sql_query($sql); $db->sql_query($sql);
break;
default: }
$sql = 'SELECT t.topic_id else
FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2 {
WHERE t.topic_moved_id = t2.topic_id $sql = 'SELECT t.topic_id
AND t.topic_time < ' . (time() - $max_age) FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
. $where; WHERE t.topic_moved_id = t2.topic_id
$result = $db->sql_query($sql); AND t.topic_time < ' . (time() - $max_age)
. $where;
$result = $db->sql_query($sql);
$topic_ids = array(); $topic_ids = array();
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$topic_ids[] = $row['topic_id']; $topic_ids[] = $row['topic_id'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
if (sizeof($topic_ids)) if (sizeof($topic_ids))
{ {
$sql = 'DELETE FROM ' . TOPICS_TABLE . ' $sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $topic_ids); WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
$db->sql_query($sql); $db->sql_query($sql);
} }
break;
} }
if ($auto_sync) if ($auto_sync)
@ -1203,41 +1201,37 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
switch ($mode) switch ($mode)
{ {
case 'topic_moved': case 'topic_moved':
switch ($db->sql_layer) if ($db->multi_table_deletion)
{ {
case 'mysql4': $sql = 'DELETE FROM ' . TOPICS_TABLE . '
case 'mysqli': USING ' . TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
$sql = 'DELETE FROM ' . TOPICS_TABLE . ' WHERE t1.topic_moved_id = t2.topic_id
USING ' . TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2 AND t1.forum_id = t2.forum_id";
WHERE t1.topic_moved_id = t2.topic_id $db->sql_query($sql);
AND t1.forum_id = t2.forum_id"; }
$db->sql_query($sql); else
break; {
$sql = 'SELECT t1.topic_id
FROM ' .TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
WHERE t1.topic_moved_id = t2.topic_id
AND t1.forum_id = t2.forum_id";
$result = $db->sql_query($sql);
default: $topic_id_ary = array();
$sql = 'SELECT t1.topic_id while ($row = $db->sql_fetchrow($result))
FROM ' .TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2 {
WHERE t1.topic_moved_id = t2.topic_id $topic_id_ary[] = $row['topic_id'];
AND t1.forum_id = t2.forum_id"; }
$result = $db->sql_query($sql); $db->sql_freeresult($result);
$topic_id_ary = array(); if (!sizeof($topic_id_ary))
while ($row = $db->sql_fetchrow($result)) {
{ return;
$topic_id_ary[] = $row['topic_id']; }
}
$db->sql_freeresult($result);
if (!sizeof($topic_id_ary)) $sql = 'DELETE FROM ' . TOPICS_TABLE . '
{ WHERE ' . $db->sql_in_set('topic_id', $topic_id_ary);
return; $db->sql_query($sql);
}
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $topic_id_ary);
$db->sql_query($sql);
break;
} }
break; break;
@ -2167,16 +2161,12 @@ function cache_moderators()
$cache->destroy('sql', MODERATOR_CACHE_TABLE); $cache->destroy('sql', MODERATOR_CACHE_TABLE);
// Clear table // Clear table
switch ($db->sql_layer) if ($db->truncate)
{ {
case 'sqlite': $db->sql_query('TRUNCATE TABLE ' . MODERATOR_CACHE_TABLE);
case 'firebird': else
$db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE); {
break; $db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
default:
$db->sql_query('TRUNCATE TABLE ' . MODERATOR_CACHE_TABLE);
break;
} }
// We add moderators who have forum moderator permissions without an explicit ACL_NEVER setting // We add moderators who have forum moderator permissions without an explicit ACL_NEVER setting
@ -2609,39 +2599,36 @@ function update_foes($group_id = false, $user_id = false)
return; return;
} }
switch ($db->sql_layer) if ($db->multi_table_deletion)
{ {
case 'mysqli': $sql = 'DELETE FROM' . ZEBRA_TABLE . ' z
case 'mysql4': USING ' . USER_GROUP_TABLE . ' ug
$sql = 'DELETE ' . (($db->sql_layer === 'mysqli' || version_compare($db->mysql_version, '4.1', '>=')) ? 'z.*' : ZEBRA_TABLE) . ' WHERE z.zebra_id = ug.user_id
FROM ' . ZEBRA_TABLE . ' z, ' . USER_GROUP_TABLE . ' ug AND z.foe = 1
WHERE z.zebra_id = ug.user_id AND ' . $db->sql_in_set('ug.group_id', $groups);
AND z.foe = 1 $db->sql_query($sql);
AND ' . $db->sql_in_set('ug.group_id', $groups); }
else
{
$sql = 'SELECT user_id
FROM ' . USER_GROUP_TABLE . '
WHERE ' . $db->sql_in_set('group_id', $groups);
$result = $db->sql_query($sql);
$users = array();
while ($row = $db->sql_fetchrow($result))
{
$users[] = (int) $row['user_id'];
}
$db->sql_freeresult($result);
if (sizeof($users))
{
$sql = 'DELETE FROM ' . ZEBRA_TABLE . '
WHERE ' . $db->sql_in_set('zebra_id', $users) . '
AND foe = 1';
$db->sql_query($sql); $db->sql_query($sql);
break; }
default:
$sql = 'SELECT user_id
FROM ' . USER_GROUP_TABLE . '
WHERE ' . $db->sql_in_set('group_id', $groups);
$result = $db->sql_query($sql);
$users = array();
while ($row = $db->sql_fetchrow($result))
{
$users[] = (int) $row['user_id'];
}
$db->sql_freeresult($result);
if (sizeof($users))
{
$sql = 'DELETE FROM ' . ZEBRA_TABLE . '
WHERE ' . $db->sql_in_set('zebra_id', $users) . '
AND foe = 1';
$db->sql_query($sql);
}
break;
} }
return; return;

View file

@ -146,8 +146,8 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
$read_tracking_join = $read_tracking_select = ''; $read_tracking_join = $read_tracking_select = '';
} }
$sql = "SELECT t.*$read_tracking_select $sql = "SELECT t.topic_id
FROM " . TOPICS_TABLE . " t $read_tracking_join FROM " . TOPICS_TABLE . " t
WHERE t.forum_id IN($forum_id, 0) WHERE t.forum_id IN($forum_id, 0)
" . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND t.topic_approved = 1') . " " . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND t.topic_approved = 1') . "
$limit_time_sql $limit_time_sql
@ -155,10 +155,21 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
$result = $db->sql_query_limit($sql, $topics_per_page, $start); $result = $db->sql_query_limit($sql, $topics_per_page, $start);
$topic_list = $topic_tracking_info = array(); $topic_list = $topic_tracking_info = array();
while ($row = $db->sql_fetchrow($result))
{
$topic_list[] = $row['topic_id'];
}
$db->sql_freeresult($result);
$sql = "SELECT t.*$read_tracking_select
FROM " . TOPICS_TABLE . " t $read_tracking_join
WHERE " . $db->sql_in_set('t.topic_id', $topic_list);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$topic_rows[$row['topic_id']] = $row; $topic_rows[$row['topic_id']] = $row;
$topic_list[] = $row['topic_id'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
@ -181,10 +192,12 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
} }
} }
foreach ($topic_rows as $topic_id => $row) foreach ($topic_list as $topic_id)
{ {
$topic_title = ''; $topic_title = '';
$row = &$topic_rows[$topic_id];
$replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; $replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies'];
if ($row['topic_status'] == ITEM_MOVED) if ($row['topic_status'] == ITEM_MOVED)

View file

@ -1251,28 +1251,10 @@ class parse_message extends bbcode_firstpass
// NOTE: obtain_* function? chaching the table contents? // NOTE: obtain_* function? chaching the table contents?
// For now setting the ttl to 10 minutes // For now setting the ttl to 10 minutes
switch ($db->sql_layer) $sql = 'SELECT *
{ FROM ' . SMILIES_TABLE . '
case 'mssql': ORDER BY ' . $db->sql_function('length_varchar', 'code') . ' DESC';
case 'mssql_odbc':
$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY LEN(code) DESC';
break;
case 'firebird':
$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY CHAR_LENGTH(code) DESC';
break;
// LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure...
default:
$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY LENGTH(code) DESC';
break;
}
$result = $db->sql_query($sql, 600); $result = $db->sql_query($sql, 600);
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))

View file

@ -864,14 +864,14 @@ class fulltext_native extends search_backend
} }
else else
{ {
if ($db->sql_layer == 'sqlite') if ($db->count_distinct)
{ {
$sql = 'SELECT COUNT(topic_id) as total_results $sql = 'SELECT COUNT(DISTINCT t.topic_id) as total_results';
FROM (SELECT DISTINCT t.topic_id';
} }
else else
{ {
$sql = 'SELECT COUNT(DISTINCT t.topic_id) as total_results'; $sql = 'SELECT COUNT(topic_id) as total_results
FROM (SELECT DISTINCT t.topic_id';
} }
$sql .= ' FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p $sql .= ' FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p
@ -881,7 +881,7 @@ class fulltext_native extends search_backend
$m_approve_fid_sql $m_approve_fid_sql
$sql_fora $sql_fora
AND t.topic_id = p.topic_id AND t.topic_id = p.topic_id
$sql_time" . (($db->sql_layer == 'sqlite') ? ')' : ''); $sql_time" . (($db->count_distinct) ? '' : ')');
} }
$result = $db->sql_query($sql); $result = $db->sql_query($sql);

View file

@ -1047,31 +1047,10 @@ $template->assign_vars(array(
// only show recent searches to search administrators // only show recent searches to search administrators
if ($auth->acl_get('a_search')) if ($auth->acl_get('a_search'))
{ {
// Handle large objects differently for Oracle and MSSQL $sql = 'SELECT search_time, search_keywords
switch ($db->sql_layer) FROM ' . SEARCH_RESULTS_TABLE . '
{ WHERE ' . $db->sql_function('length_text', 'search_keywords') . ' > 0
case 'oracle': ORDER BY search_time DESC';
$sql = 'SELECT search_time, search_keywords
FROM ' . SEARCH_RESULTS_TABLE . '
WHERE dbms_lob.getlength(search_keywords) > 0
ORDER BY search_time DESC';
break;
case 'mssql':
case 'mssql_odbc':
$sql = 'SELECT search_time, search_keywords
FROM ' . SEARCH_RESULTS_TABLE . '
WHERE DATALENGTH(search_keywords) > 0
ORDER BY search_time DESC';
break;
default:
$sql = 'SELECT search_time, search_keywords
FROM ' . SEARCH_RESULTS_TABLE . '
WHERE search_keywords <> \'\'
ORDER BY search_time DESC';
break;
}
$result = $db->sql_query_limit($sql, 5); $result = $db->sql_query_limit($sql, 5);
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))

View file

@ -140,7 +140,7 @@ if ($id)
} }
// Expire time of seven days if not recached // Expire time of seven days if not recached
$expire_time = 7*86400; $expire_time = 7 * 86400;
$recache = false; $recache = false;
// Re-cache stylesheet data if necessary // Re-cache stylesheet data if necessary
@ -177,7 +177,10 @@ if ($id)
if ($recache) if ($recache)
{ {
include_once($phpbb_root_path . 'includes/acp/acp_styles.' . $phpEx); if (!class_exists('acp_styles'))
{
include($phpbb_root_path . 'includes/acp/acp_styles.' . $phpEx);
}
$theme['theme_data'] = acp_styles::db_theme_data($theme); $theme['theme_data'] = acp_styles::db_theme_data($theme);
$theme['theme_mtime'] = $update_time; $theme['theme_mtime'] = $update_time;

View file

@ -405,28 +405,38 @@ else if (empty($active_forum_ary['exclude_forum_id']))
else else
{ {
$get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']); $get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']);
$sql_where = (sizeof($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id; $sql_where = $db->sql_in_set('t.forum_id', $get_forum_ids);
} }
// Grab just the sorted topic ids
$sql = 'SELECT t.topic_id
FROM ' . TOPICS_TABLE . " t
WHERE $sql_where
AND t.topic_type IN (" . POST_NORMAL . ', ' . POST_STICKY . ")
$sql_approved
$sql_limit_time
ORDER BY t.topic_type " . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order;
$result = $db->sql_query_limit($sql, $sql_limit, $sql_start);
while ($row = $db->sql_fetchrow($result))
{
$topic_list[] = (int) $row['topic_id'];
}
$db->sql_freeresult($result);
// SQL array for obtaining topics/stickies // SQL array for obtaining topics/stickies
$sql_array = array( $sql_array = array(
'SELECT' => $sql_array['SELECT'], 'SELECT' => $sql_array['SELECT'],
'FROM' => $sql_array['FROM'], 'FROM' => $sql_array['FROM'],
'LEFT_JOIN' => $sql_array['LEFT_JOIN'], 'LEFT_JOIN' => $sql_array['LEFT_JOIN'],
'WHERE' => $sql_where . ' 'WHERE' => $db->sql_in_set('t.topic_id', $topic_list),
AND t.topic_type IN (' . POST_NORMAL . ', ' . POST_STICKY . ")
$sql_approved
$sql_limit_time",
'ORDER_BY' => 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order,
); );
// If store_reverse, then first obtain topics, then stickies, else the other way around... // If store_reverse, then first obtain topics, then stickies, else the other way around...
// Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because // Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because
// the number of stickies are not known // the number of stickies are not known
$sql = $db->sql_build_query('SELECT', $sql_array); $sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query_limit($sql, $sql_limit, $sql_start); $result = $db->sql_query($sql);
$shadow_topic_list = array(); $shadow_topic_list = array();
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
@ -437,7 +447,6 @@ while ($row = $db->sql_fetchrow($result))
} }
$rowset[$row['topic_id']] = $row; $rowset[$row['topic_id']] = $row;
$topic_list[] = $row['topic_id'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);

View file

@ -97,23 +97,21 @@ $guest_counter = 0;
// Get number of online guests (if we do not display them) // Get number of online guests (if we do not display them)
if (!$show_guests) if (!$show_guests)
{ {
switch ($db->sql_layer) if ($db->count_distinct)
{ {
case 'sqlite': $sql = 'SELECT COUNT(DISTINCT session_ip) as num_guests
$sql = 'SELECT COUNT(session_ip) as num_guests
FROM (
SELECT DISTINCT session_ip
FROM ' . SESSIONS_TABLE . '
WHERE session_user_id = ' . ANONYMOUS . '
AND session_time >= ' . (time() - ($config['load_online_time'] * 60)) .
')';
break;
default:
$sql = 'SELECT COUNT(DISTINCT session_ip) as num_guests
FROM ' . SESSIONS_TABLE . ' FROM ' . SESSIONS_TABLE . '
WHERE session_user_id = ' . ANONYMOUS . ' WHERE session_user_id = ' . ANONYMOUS . '
AND session_time >= ' . (time() - ($config['load_online_time'] * 60)); AND session_time >= ' . (time() - ($config['load_online_time'] * 60));
else
{
$sql = 'SELECT COUNT(session_ip) as num_guests
FROM (
SELECT DISTINCT session_ip
FROM ' . SESSIONS_TABLE . '
WHERE session_user_id = ' . ANONYMOUS . '
AND session_time >= ' . (time() - ($config['load_online_time'] * 60)) .
')';
break; break;
} }
$result = $db->sql_query($sql); $result = $db->sql_query($sql);