2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * SQL import plugin for phpMyAdmin
7 * @package phpMyAdmin-Import
9 if (! defined('PHPMYADMIN')) {
16 if (isset($plugin_list)) {
17 $plugin_list['sql'] = array(
20 'options_text' => 'strOptions',
22 $compats = PMA_DBI_getCompatibilities();
23 if (count($compats) > 0) {
25 foreach($compats as $val) {
28 $plugin_list['sql']['options'] = array(
31 'name' => 'compatibility',
32 'text' => 'strSQLCompatibility',
35 'manual_MySQL_Database_Administration',
41 'name' => 'no_auto_value_on_zero',
42 'text' => 'strDoNotAutoIncrementZeroValues',
44 'manual_MySQL_Database_Administration',
46 'sqlmode_no_auto_value_on_zero'
53 /* We do not define function when plugin is just queried for information above */
58 // Defaults for parser
63 $big_value = 2147483647;
65 if (isset($_POST['sql_delimiter'])) {
66 $sql_delimiter = $_POST['sql_delimiter'];
71 // Handle compatibility options
73 if (isset($_REQUEST['sql_compatibility']) && 'NONE' != $_REQUEST['sql_compatibility']) {
74 $sql_modes[] = $_REQUEST['sql_compatibility'];
76 if (isset($_REQUEST['sql_no_auto_value_on_zero'])) {
77 $sql_modes[] = 'NO_AUTO_VALUE_ON_ZERO';
79 if (count($sql_modes) > 0) {
80 PMA_DBI_try_query('SET SQL_MODE="' . implode(',', $sql_modes) . '"');
85 * will be set in PMA_importGetNextChunk()
87 * @global boolean $GLOBALS['finished']
89 $GLOBALS['finished'] = false;
91 while (!($GLOBALS['finished'] && $i >= $len) && !$error && !$timeout_passed) {
92 $data = PMA_importGetNextChunk();
93 if ($data === FALSE) {
94 // subtract data we didn't handle yet and stop processing
95 $offset -= strlen($buffer);
97 } elseif ($data === TRUE) {
98 // Handle rest of buffer
100 // Append new data to buffer
104 // Do not parse string when we're not at the end and don't have ; inside
105 if ((strpos($buffer, $sql_delimiter, $i) === FALSE) && !$GLOBALS['finished']) {
109 // Current length of our buffer
110 $len = strlen($buffer);
112 // Grab some SQL queries out of it
114 $found_delimiter = false;
115 // Find first interesting character
117 // this is about 7 times faster that looking for each sequence i
118 // one by one with strpos()
119 if (preg_match('/(\'|"|#|-- |\/\*|`|(?i)DELIMITER)/', $buffer, $matches, PREG_OFFSET_CAPTURE
, $i)) {
120 // in $matches, index 0 contains the match for the complete
121 // expression but we don't use it
122 $first_position = $matches[1][1];
124 $first_position = $big_value;
127 * @todo we should not look for a delimiter that might be
128 * inside quotes (or even double-quotes)
130 // the cost of doing this one with preg_match() would be too high
131 $first_sql_delimiter = strpos($buffer, $sql_delimiter, $i);
132 if ($first_sql_delimiter === FALSE) {
133 $first_sql_delimiter = $big_value;
135 $found_delimiter = true;
138 // set $i to the position of the first quote, comment.start or delimiter found
139 $i = min($first_position, $first_sql_delimiter);
141 if ($i == $big_value) {
142 // none of the above was found in the string
145 if (!$GLOBALS['finished']) {
148 // at the end there might be some whitespace...
149 if (trim($buffer) == '') {
154 // We hit end of query, go there!
155 $i = strlen($buffer) - 1;
158 // Grab current character
162 if (strpos('\'"`', $ch) !== FALSE) {
167 $pos = strpos($buffer, $quote, $i +
1);
168 // No quote? Too short string
169 if ($pos === FALSE) {
170 // We hit end of string => unclosed quote, but we handle it as end of query
171 if ($GLOBALS['finished']) {
175 $found_delimiter = false;
178 // Was not the quote escaped?
180 while ($buffer[$j] == '\\') $j--;
181 // Even count means it was not escaped
182 $endq = (((($pos - 1) - $j) %
2) == 0);
186 if ($first_sql_delimiter < $pos) {
187 $found_delimiter = false;
194 // Aren't we at the end?
195 if ($GLOBALS['finished'] && $i == $len) {
202 // Not enough data to decide
203 if ((($i == ($len - 1) && ($ch == '-' ||
$ch == '/'))
204 ||
($i == ($len - 2) && (($ch == '-' && $buffer[$i +
1] == '-')
205 ||
($ch == '/' && $buffer[$i +
1] == '*')))) && !$GLOBALS['finished']) {
211 ||
($i < ($len - 1) && $ch == '-' && $buffer[$i +
1] == '-'
212 && (($i < ($len - 2) && $buffer[$i +
2] <= ' ')
213 ||
($i == ($len - 1) && $GLOBALS['finished'])))
214 ||
($i < ($len - 1) && $ch == '/' && $buffer[$i +
1] == '*')
216 // Copy current string to SQL
217 if ($start_pos != $i) {
218 $sql .= substr($buffer, $start_pos, $i - $start_pos);
222 $i = strpos($buffer, $ch == '/' ?
'*/' : "\n", $i);
223 // didn't we hit end of string?
225 if ($GLOBALS['finished']) {
233 // Check for MySQL conditional comments and include them as-is
234 if ($buffer[$j +
2] == '!') {
235 $comment = substr($buffer, $j +
3, $i - $j - 3);
236 if (preg_match('/^[0-9]{5}/', $comment, $version)) {
237 if ($version[0] <= PMA_MYSQL_INT_VERSION
) {
238 $sql .= substr($comment, 5);
248 // Next query part will start here
250 // Aren't we at the end?
257 // Change delimiter, if redefined, and skip it (don't send to server!)
258 if (strtoupper(substr($buffer, $i, 9)) == "DELIMITER"
259 && ($buffer[$i +
9] <= ' ')
261 && strpos($buffer, "\n", $i +
11) !== FALSE) {
262 $new_line_pos = strpos($buffer, "\n", $i +
10);
263 $sql_delimiter = substr($buffer, $i +
10, $new_line_pos - $i - 10);
264 $i = $new_line_pos +
1;
265 // Next query part will start here
271 if ($found_delimiter ||
($GLOBALS['finished'] && ($i == $len - 1))) {
273 if ($start_pos < $len) {
274 $length_to_grab = $i - $start_pos;
276 if (! $found_delimiter) {
279 $tmp_sql .= substr($buffer, $start_pos, $length_to_grab);
280 unset($length_to_grab);
282 // Do not try to execute empty SQL
283 if (! preg_match('/^([\s]*;)*$/', trim($tmp_sql))) {
285 PMA_importRunQuery($sql, substr($buffer, 0, $i +
strlen($sql_delimiter)));
286 $buffer = substr($buffer, $i +
strlen($sql_delimiter));
288 $len = strlen($buffer);
292 // Any chance we will get a complete query?
293 //if ((strpos($buffer, ';') === FALSE) && !$GLOBALS['finished']) {
294 if ((strpos($buffer, $sql_delimiter) === FALSE) && !$GLOBALS['finished']) {
302 } // End of parser loop
303 } // End of import loop
304 // Commit any possible data in buffers
305 PMA_importRunQuery('', substr($buffer, 0, $len));
306 PMA_importRunQuery();