Files
phpmyadmin/read_dump.php3
Loïc Chapeaux e34a463b3c * moved the 'split_sql_file()' function from the library to the main script, then removed the library;
* tried some fixes for bugs with comments characters in dump files (see bug #444279) and taked into account "-- " styled comments;
* disactivated the "/*!...*/" syntax for MySQL < 3.22.07;
* optimized the 'split_sql_file()' function.
2001-09-11 09:26:40 +00:00

284 lines
9.3 KiB
PHP

<?php
/* $Id$ */
/**
* Removes comment lines and splits up large sql files into individual queries
*
* Last revision: September 11, 2001 - loic1
*
* @param string the sql commands
* @param string the end of command line delimiter
* @param integer the MySQL release number (because certains php3 versions
* can't get the value of a constant from within a function)
*
* @return array the splitted sql commands
*
* @access public
*/
function split_sql_file($sql, $delimiter, $release)
{
$sql = trim($sql);
$sql_len = strlen($sql);
$char = '';
$ret = array();
$string_start = '';
$in_string = FALSE;
$in_comment = FALSE;
for ($i = 0; $i < $sql_len; ++$i) {
$char = $sql[$i];
// We are in a string, check for not escaped end of strings except for
// backquotes than cannot be escaped
if ($in_string) {
while (1) {
$i = strpos($sql, $string_start, $i);
// No end of string found -> add the current substring to the
// returned array
if (!$i) {
$ret[] = $sql;
return $ret;
}
// It's trully the end of the string -> move to the next
// character
else if (($string_start == '`')
|| (($i > 1 && $sql[$i-1] . $sql[$i-2] != '\\\\')
|| ($sql[0] != '\\'))) {
$string_start = '';
$in_string = FALSE;
break;
} // end if... elseif
} // end while
} // end if ($in_string)
// We are in a comment, add the parsed part to the returned array and
// move to the next end of line
else if ($in_comment) {
// comment starting position in string depends on the comment type
$ret_end = (($sql[$i-1] == '#') ? $i-1 : $i-3);
if (ereg('[^[:space:]]+', substr($sql, 0, $ret_end))) {
$ret[] = substr($sql, 0, $ret_end);
}
// if no "\n" exits in the remaining string, checks for "\r" (Mac
// eol style)
$eol_to_find = (strpos($sql, "\012", $i)) ? "\012" : "\015";
$sql = strstr($sql, $eol_to_find);
if ($sql == '' || empty($sql[1])) {
// The submited statement(s) end(s) by a comment -> stop
// parsing
return $ret;
} else {
$sql = ltrim(substr($sql, 1));
$sql_len = strlen($sql);
if ($sql_len) {
$i = -1;
$in_comment = FALSE;
} else {
// The submited statement(s) end(s) here
return $ret;
} // end if...else
} // end if...else
} // end if ($in_comment)
// If delimiter found, add the parsed part to the returned array
else if ($char == $delimiter) {
$ret[] = substr($sql, 0, $i);
$sql = ltrim(substr($sql, min($i + 2, $sql_len)));
$sql_len = strlen($sql);
if ($sql_len) {
$i = -1;
} else {
// The submited statement(s) end(s) here
return $ret;
}
} // end if ($char == $delimiter)
// We are neither in a string nor in a comment, and nor the current
// character is a delimiter...
else {
// ... first check for start of strings...
if (($char == '"') || ($char == '\'') || ($char == '`')) {
$in_string = TRUE;
$string_start = $char;
}
// ... then check for start of a comment...
else if ($char == '#'
|| ($char == ' ' && $i > 1 && $sql[$i-2] . $sql[$i-1] == '--')) {
$in_comment = TRUE;
}
// ... and finally disactivate the "/*!...*/" syntax if
// MySQL < 3.22.07
else if ($release < 32270
&& ($char == '!' && $i > 1 && $sql[$i-2] . $sql[$i-1] == '/*')) {
$sql[$i] = ' ';
}
} // end else
} // end for
// add any rest to the returned array
if (!empty($sql)) {
$ret[] = $sql;
}
return $ret;
} // end of the 'split_sql_file()' function
/**
* Increases the max. allowed time to run a script
*/
@set_time_limit(10000);
/**
* Gets some core libraries
*/
require('./libraries/grab_globals.lib.php3');
require('./libraries/common.lib.php3');
/**
* Set up default values for some variables and
*/
$view_bookmark = 0;
$sql_bookmark = isset($sql_bookmark) ? $sql_bookmark : '';
$sql_query = isset($sql_query) ? $sql_query : '';
$sql_file = !empty($sql_file) ? $sql_file : 'none';
/**
* Bookmark Support: get a query back from bookmark if required
*/
if (!empty($id_bookmark)) {
include('./libraries/bookmark.lib.php3');
switch($action_bookmark) {
case 0: // bookmarked query that have to be run
$sql_query = query_bookmarks($db, $cfgBookmark, $id_bookmark);
break;
case 1: // bookmarked query that have to be displayed
$sql_query = query_bookmarks($db, $cfgBookmark, $id_bookmark);
$view_bookmark = 1;
break;
case 2: // bookmarked query that have to be deleted
$sql_query = delete_bookmarks($db, $cfgBookmark, $id_bookmark);
break;
}
} // end if
/**
* Prepares the sql query
*/
// Gets the query from a file if required
if ($sql_file != 'none') {
// loic1: php < 4.05 for windows seems not to list the regexp test
// if (ereg('^php[0-9A-Za-z_.-]+$', basename($sql_file))) {
if (file_exists($sql_file)) {
$sql_query = fread(fopen($sql_file, 'r'), filesize($sql_file));
if (get_magic_quotes_runtime() == 1) {
$sql_query = stripslashes($sql_query);
}
}
}
else if (empty($id_bookmark) && get_magic_quotes_gpc() == 1) {
$sql_query = stripslashes($sql_query);
}
$sql_query = trim($sql_query);
// $sql_query come from the query textarea, if it's a reposted query gets its
// 'true' value
if (!empty($prev_sql_query)) {
$prev_sql_query = urldecode($prev_sql_query);
if ($sql_query == trim(htmlspecialchars($prev_sql_query))) {
$sql_query = $prev_sql_query;
}
}
// Drop database is not allowed -> ensure the query can be run
if (!$cfgAllowUserDropDatabase
&& eregi('DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE ', $sql_query)) {
// Checks if the user is a Superuser
// TODO: set a global variable with this information
// loic1: optimized query
$result = @mysql_query('USE mysql');
if (mysql_error()) {
include('./header.inc.php3');
mysql_die($strNoDropDatabases);
}
}
define('PMA_CHK_DROP', 1);
/**
* Executes the query
*/
if ($sql_query != '') {
$pieces = split_sql_file($sql_query, ';', MYSQL_INT_VERSION);
$pieces_count = count($pieces);
// Copy of the cleaned sql statement for display purpose only (see near the
// beginning of "db_details.php3" & "tbl_properties.php3")
if ($sql_file != 'none' && $pieces_count > 10) {
$sql_query_cpy = $sql_query = '';
} else {
$sql_query_cpy = implode(";\n", $pieces) . ';';
}
// Only one query to run
if ($pieces_count == 1 && !empty($pieces[0]) && $view_bookmark == 0) {
// loic1: remove non alphabetic characters from the beginning of the
// query
// $sql_query = trim($pieces[0]);
$sql_query = eregi_replace('^[^a-aA-Z]', '', $pieces[0]);
// sql.php3 will stripslash the query if get_magic_quotes_gpc
if (get_magic_quotes_gpc() == 1) {
$sql_query = addslashes($sql_query);
}
if (eregi('^(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)', $sql_query)) {
$reload = 1;
}
include('./sql.php3');
exit();
}
// Runs multiple queries
else if (mysql_select_db($db)) {
for ($i = 0; $i < $pieces_count; $i++) {
$a_sql_query = trim($pieces[$i]);
if (!empty($a_sql_query) && $a_sql_query[0] != '#') {
$result = mysql_query($a_sql_query);
if ($result == FALSE) { // readdump failed
$my_die = $a_sql_query;
break;
}
}
if (!isset($reload) && eregi('^(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)', $a_sql_query)) {
$reload = 1;
}
} // end for
} // end else if
unset($pieces);
} // end if
/**
* Go back to the calling script
*/
$js_to_run = 'functions.js';
require('./header.inc.php3');
if (isset($my_die)) {
mysql_die('', $my_die);
}
// Be nice with bandwidth...
if ($sql_query_cpy == '') {
$message = "$strSuccess&nbsp:<br />$strTheContent ($pieces_count $strInstructions)&nbsp;";
} else {
$message = $strSuccess;
}
if (!isset($goto)
|| ($goto != 'db_details.php3' && $goto != 'tbl_properties.php3')) {
$goto = 'db_details.php3';
}
require('./' . $goto);
?>