<?php
/**
*
* @package dbal
* @version $Id$
* @copyright (c) 2007 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Database Tools for handling cross-db actions such as altering columns, etc.
* Currently not supported is returning SQL for creating tables.
*
* @package dbal
* @note currently not used within phpBB3, but may be utilized later.
*/
if (!function_exists('get_available_dbms')) {
require($phpbb_root_path . 'includes/functions_install.' . $phpEx);
}
class mysql_db_tools
{
var $tables = array("acl_groups",
"acl_options",
"acl_roles",
"acl_roles_data",
"acl_users",
"attachments",
"banlist",
"bbcodes",
"bookmarks",
"bots",
"config",
"confirm",
"disallow",
"drafts",
"extension_groups",
"extensions",
"forums",
"forums_access",
"forums_track",
"forums_watch",
"groups",
"icons",
"log",
"login_attempts",
"moderator_cache",
"modules",
"poll_options",
"poll_votes",
"posts",
"privmsgs",
"privmsgs_folder",
"privmsgs_rules",
"privmsgs_to",
"profile_fields",
"profile_fields_data",
"profile_fields_lang",
"profile_lang",
"ranks",
"reports",
"reports_reasons",
"search_results",
"search_wordlist",
"search_wordmatch",
"sessions",
"sessions_keys",
"sitelist",
"smilies",
"styles",
"styles_imageset",
"styles_imageset_data",
"styles_template",
"styles_template_data",
"styles_theme",
"topics",
"topics_posted",
"topics_track",
"topics_watch",
"user_group",
"users",
"warnings",
"words",
"zebra"
);
var $restore = array( 'restore_config' => array( "forums",
"forums_access",
"forums_track",
"forums_watch",
),
'restore_forums' => array("posts",
),
'restore_posts' => array("banlist",
"topics",
"topics_posted",
));
var $comands = array('CREATE',
'TABLE',
'DROP',
'LOCK',
'INSERT',
'IF',
'TABLES',
'EXISTS',
'INTO',
);
var $sql = array();
var $prefix = array();
var $table_keys = array();
function mysql_db_tools($db_tools, $dump)
{
$this->db_tools = $db_tools;
$this->dbms_type_map = $db_tools->dbms_type_map['mysql_41'];
}
function get_table($sql)
{
$sql = str_pad($sql, strlen($sql) + 1);
while($command = substr($sql, 0, strpos($sql, " ")))
{
$sql = substr($sql, strpos($sql, " ") + 1, strlen($sql));
if (!in_array($command, $this->comands, true))
break;
}
return trim($command, "`'");
}
function get_command($sql = false, $restore = false)
{
if($sql)
{
$this->sql = $sql;
if(!$this->delete_comment()) return false;
}
if(!$restore)
{
return substr($this->sql, 0, strpos($this->sql, " "));
}
else
{
if (in_array($this->get_table($this->sql), $this->restore, true))
{
return substr($this->sql, 0, strpos($this->sql, " "));
}
elseif(substr($this->sql, 0, strpos($this->sql, " ")) == 'UNLOCK') return 'UNLOCK';
return false;
}
}
function get_create($sql)
{
$pos = $start_lenght = 0;
$table_name = $this->get_table($sql);
$replace = ltrim(preg_replace(array("/^.*?\(/", "/\).*?$/", "'[\r\n]+'") ,
array("", "", ""), $sql));
$rows['KEYS'] = array();
while ($chr = ord($replace))
{
switch ($chr)
{
case 39:
case 96:
$pos = strpos(substr($replace, 1), $chr);
$column_name = substr($replace, 1, $pos);
$replace = ltrim(substr($replace, $pos + 2));
if (($set = strpos($replace, "(")) < ($position_separate_string_sql_create = strpos($replace, ",")) || $position_separate_string_sql_create === false) $position_separate_string_sql_create = $this->position_separate($replace, ")", ",");
$string = substr($replace, 0, $position_separate_string_sql_create);
$column_data = $this->preg_dbms_type_map($string);
$replace = ltrim(substr($replace, $position_separate_string_sql_create + 2));
$rows['COLUMNS'][$column_name][0] = $column_data;
if(($default = strpos($string, 'DEFAULT')) !== false)
{
$default = substr(substr($string, $default), strpos($string, " "));
$rows['COLUMNS'][$column_name][1] = trim($default, " '");
}
if(stripos($string, 'AUTO_INCREMENT') !== false)$rows['COLUMNS'][$column_name][2] = 'auto_increment';
elseif (stripos($string, 'COLLATE utf8') !== false) $rows['COLUMNS'][$column_name][2] = 'true_sort';
break;
default:
$func = substr($replace, 0, strpos($replace, " "));
$position_separate_string_sql_create = $this->position_separate($replace, ")", ",");
$str = substr($replace, 0, $position_separate_string_sql_create);
$replace = ltrim(substr($replace, $position_separate_string_sql_create + 2));
switch($func)
{
case 'PRIMARY':
$rows['PRIMARY_KEY'] = $this->key_data($str, $func);
break;
default:
if(!isset($rows['KEYS'])) $rows['KEYS'] = array();
$rows['KEYS'] = array_merge($rows['KEYS'], $this->key_data($str, $func));
}
// End case
}
}
if(isset($rows['PRIMARY_KEY']) && count($rows['KEYS']))
{
foreach($rows['KEYS'] as $keys)
{
if ($rows['KEYS'][0] != 'KEY')
{
$this->table_keys[$table_name] = $table_name;
break;
}
}
}
return $rows;
}
function delete_comment()
{
$sql = explode("\n", $this->sql);
foreach ($sql as $key => $s)
{
$sql[$key] = preg_replace(array("/^--.*?$/","/^\/\*.*?\*\/$/"), array("",""), $sql[$key]);
if (!strlen($sql[$key])) unset($sql[$key]);
}
(!count($sql))? $this->sql = "" : $this->sql = implode("", $sql);
return count($sql);
}
/*
** Эта функция выбирает список таблиц для востановления
*/
function set_restore($prefix)
{
global $mode;
$this->restore = $this->restore[$mode];
for ($i = 0; $i < count($this->restore); $i++)
{
$this->restore[$i] = $prefix . $this->restore[$i];
}
}
/*
$add_string = mb_convert_encoding($add_string, "Windows-1251", "UTF-8");
This defaul charset for MS SQL Native Database
*/
function get_insert($sql, $table_name, $columns)
{
global $config;
if(($pos_values = strpos($sql, "VALUES")) !== false) $sql = ltrim(substr($sql, $pos_values + 6), " \n\r\t");
$count_columns = count($columns);
$column_start = 'INSERT INTO ' . $table_name . ' (';
foreach($columns as $column)
{
$column_start .= $column . ', ';
}
$column_start = substr($column_start, 0, -2) . ') ';
$numstr = 0;
while(strlen($sql))
{
$sql = ltrim($sql, " (");
$numstr = $numstr + 1;
$sqls[$numstr] = 'VALUES (';
foreach($columns as $column)
{
switch($chr = substr($sql, 0, 1))
{
case "`":
case "'":
$pos = strpos(substr($sql, 1), $chr) + 1;
for ($i = 0; $i < strlen($sql); $i = $pos)
{
if(substr($sql, $pos - 1, 1) == "\\")
{
$pos = strpos($sql, $chr, $pos + 1);
}
else break;
}
if(mb_check_encoding(($add_string = substr($sql, 1, $pos - 1)), "UTF-8") == true
&& $this->db_tools->sql_layer == 'mssqlnative'
&& $config['default_lang'] == 'ru')
// For Russian Language mssqlnative DataBase
// $string, charset "out", charset "in"
$add_string = mb_convert_encoding($add_string, "Windows-1251", "UTF-8");
elseif (mb_check_encoding(($add_string = substr($sql, 1, $pos - 1)), "UTF-8") == false
&& $this->db_tools->sql_layer != 'mssqlnative'
&& $config['default_lang'] == 'ru')
// For other DataBase Russian Language
// $string, charset "out", charset "in"
$add_string = mb_convert_encoding($add_string, "UTF-8", "Windows-1251");
$sqls[$numstr] .= '\'' .$add_string . '\', ';
$sql = ltrim(substr($sql, $pos + 2), " \n\r\t,");
break;
default:
if (48 <= $chr && $chr <= 57) die("Нет кавычек<br>" . $sql);
$sqls['intval'] = intval($sql);
$sqls[$numstr] .= $sqls['intval'] . ', ';
$sql = substr($sql, strlen($sqls['intval']));
unset($sqls['intval']);
$sql = ltrim($sql, ", \n\r\t");
}
$sql = ltrim($sql, "), \n\r\t");
}
$sqls[$numstr] = substr($sqls[$numstr], 0, -2) . ')';
$sqls[$numstr] = $column_start . $sqls[$numstr];
}
return $sqls;
}
function get_sql_to_array($prefix)
{
$this->sql = str_replace("\n", "", $this->sql);
}
function get_prefix($sql)
{
if($sql)
{
$this->sql = $sql;
$this->delete_comment();
}
$sql = preg_split("/[`\']+/", $sql);
foreach($this->tables as $t)
{
$pos = strpos($sql[1], $t);
if($pos)
{
$this->prefix[] .= substr($sql[1], 0, $pos);
break;
}
}
$this->prefix = array_unique($this->prefix);
return $this->prefix;
}
/*
**
**
*/
function key_data($str, $func)
{
switch($func)
{
case 'UNIQUE':
case 'KEY':
$key_name = trim(preg_replace(array("/^.*?[`'+].*?\(*?/", "/\(+.*?$/"),
array("", ""), $str)
, "`' ");
case 'PRIMARY':
$str = preg_replace(array("/^.*?\(/", "/\).*?$/"),
array("", ""), $str);
$key_data = explode(",",$str);
for ($i = 0; $i < count($key_data); $i++)
{
$key_data[$i] = trim($key_data[$i], "`' ");
}
break;
}
if(isset($key_name) && $key_name)
{
$key_unique[$key_name] = array($func,$key_data);
return $key_unique;
}
else return $key_data;
}
/*/////////////////////////////////////////////////////////////////////////////////
*
*
*
*//////////////////////////////////////////////////////////////////////////////////
function position_separate($string, $chr = '"', $separate = "\n")
{
if(strlen($separate) > 1) return false;
$chars = array( 40 => 41, //// ord ()
123 => 125, //// ord {}
91 => 93, //// ord []
60 => 62, //// ord < >
);
$separators = array(33, 34, 37, 39, 42, 45, 47, 63, 64, 92, 96, 124);
switch(strlen($chr))
{
case 1:
$chr = ord($chr);
//////////////////////////////////////////////////////////////////////////////////
if($char = array_search($chr, $chars)) $char = array(chr($char) => chr($chr));
elseif($char = array_search($chr, array_flip($chars))) $char = array(chr($chr) => chr($char));
elseif($char = array_search($chr, $separators)) $char = array(chr($chr) => chr($chr));
else return false;
///////////////////////////////////////////////////////////////////////////////////
$chr = chr($chr);
$pos_chr = 1;
$pos_separate = 0;
while($pos_chr > $pos_separate)
{
$pos_chr = strpos($string, ")", $pos_separate);
if(($pos_separate = strpos($string, ",", $pos_chr)) === false) return strlen($string) - 1;
}
return $pos_separate;
case 2:
print_r("In work");
return "In work";
default: return false;
}
}
function preg_dbms_type_map($column_data)
{
$type = substr($column_data, 0, strpos($column_data, ' '));
if (stripos($column_data, "UNSIGNED") !== false)
$type .= " UNSIGNED";
if ($data = array_search($type, $this->dbms_type_map)) return $data;
foreach ($this->dbms_type_map as $t => $search)
{
if (strpos($t, ":") !== false || $t == 'BOOL')
{
if(substr($search, 0, strpos($search, "(")) == substr($type, 0, strpos($type, "(")))
{
$data = $t . intval(substr($type, strpos($type, "(") + 1));
if ((strpos($column_data, ",")) !== false)
$data .= "," . intval(substr($type, strpos($type, ",") + 1));
break;
}
}
}
return $data;
}
}
?>
|