2.9.2-rc1
[phpmyadmin/arisferyanto.git] / libraries / import / sql.php
blob7c2b164f474dc20faf6744aa6b388b5ed0b237f9
1 <?php
2 /* $Id$ */
3 // vim: expandtab sw=4 ts=4 sts=4:
5 /* SQL import plugin for phpMyAdmin */
7 if (isset($plugin_list)) {
8 $plugin_list['sql'] = array(
9 'text' => 'strSQL',
10 'extension' => 'sql',
11 'options_text' => 'strSQLImportOptions',
13 $compats = PMA_DBI_getCompatibilities();
14 if (count($compats) > 0) {
15 $values = array();
16 foreach($compats as $val) {
17 $values[$val] = $val;
19 $plugin_list['sql']['options'] = array(
20 array('type' => 'select', 'name' => 'compatibility', 'text' => 'strSQLCompatibility', 'values' => $values, 'doc' => array('manual_MySQL_Database_Administration', 'Server_SQL_mode'))
23 } else {
24 /* We do not define function when plugin is just queried for information above */
25 $buffer = '';
26 // Defaults for parser
27 $sql = '';
28 $start_pos = 0;
29 $i = 0;
30 if (isset($_POST['sql_delimiter'])) {
31 $sql_delimiter = $_POST['sql_delimiter'];
32 } else {
33 $sql_delimiter = ';';
36 // Handle compatibility option
37 if (isset($_REQUEST['sql_compatibility'])) {
38 PMA_DBI_try_query('SET SQL_MODE="' . $_REQUEST['sql_compatibility'] . '"');
40 while (!($finished && $i >= $len) && !$error && !$timeout_passed) {
41 $data = PMA_importGetNextChunk();
42 if ($data === FALSE) {
43 // subtract data we didn't handle yet and stop processing
44 $offset -= strlen($buffer);
45 break;
46 } elseif ($data === TRUE) {
47 // Handle rest of buffer
48 } else {
49 // Append new data to buffer
50 $buffer .= $data;
51 // Do not parse string when we're not at the end and don't have ; inside
52 if ((strpos($buffer, $sql_delimiter) === FALSE) && !$finished) {
53 continue;
56 // Current length of our buffer
57 $len = strlen($buffer);
58 // Grab some SQL queries out of it
59 while ($i < $len) {
60 $found_delimiter = false;
61 // Find first interesting character, several strpos seem to be faster than simple loop in php:
62 //while (($i < $len) && (strpos('\'";#-/', $buffer[$i]) === FALSE)) $i++;
63 //if ($i == $len) break;
64 $oi = $i;
65 $p1 = strpos($buffer, '\'', $i);
66 if ($p1 === FALSE) {
67 $p1 = 2147483647;
69 $p2 = strpos($buffer, '"', $i);
70 if ($p2 === FALSE) {
71 $p2 = 2147483647;
73 $p3 = strpos($buffer, $sql_delimiter, $i);
74 if ($p3 === FALSE) {
75 $p3 = 2147483647;
76 } else {
77 $found_delimiter = true;
79 $p4 = strpos($buffer, '#', $i);
80 if ($p4 === FALSE) {
81 $p4 = 2147483647;
83 $p5 = strpos($buffer, '--', $i);
84 if ($p5 === FALSE || $p5 >= ($len - 2) || $buffer[$p5 + 2] > ' ') {
85 $p5 = 2147483647;
87 $p6 = strpos($buffer, '/*', $i);
88 if ($p6 === FALSE) {
89 $p6 = 2147483647;
91 $p7 = strpos($buffer, '`', $i);
92 if ($p7 === FALSE) {
93 $p7 = 2147483647;
95 $i = min ($p1, $p2, $p3, $p4, $p5, $p6, $p7);
96 unset($p1, $p2, $p3, $p4, $p5, $p6, $p7);
97 if ($i == 2147483647) {
98 $i = $oi;
99 if (!$finished) {
100 break;
102 // at the end there might be some whitespace...
103 if (trim($buffer) == '') {
104 $buffer = '';
105 $len = 0;
106 break;
108 // We hit end of query, go there!
109 $i = strlen($buffer) - 1;
112 // Grab current character
113 $ch = $buffer[$i];
115 // Quotes
116 if (!(strpos('\'"`', $ch) === FALSE)) {
117 $quote = $ch;
118 $endq = FALSE;
119 while (!$endq) {
120 // Find next quote
121 $pos = strpos($buffer, $quote, $i + 1);
122 // No quote? Too short string
123 if ($pos === FALSE) {
124 // We hit end of string => unclosed quote, but we handle it as end of query
125 if ($finished) {
126 $endq = TRUE;
127 $i = $len - 1;
129 break;
131 // Was not the quote escaped?
132 $j = $pos - 1;
133 while ($buffer[$j] == '\\') $j--;
134 // Even count means it was not escaped
135 $endq = (((($pos - 1) - $j) % 2) == 0);
136 // Skip the string
137 $i = $pos;
139 if (!$endq) {
140 break;
142 $i++;
143 // Aren't we at the end?
144 if ($finished && $i == $len) {
145 $i--;
146 } else {
147 continue;
151 // Not enough data to decide
152 if ((($i == ($len - 1) && ($ch == '-' || $ch == '/'))
153 || ($i == ($len - 2) && (($ch == '-' && $buffer[$i + 1] == '-') || ($ch == '/' && $buffer[$i + 1] == '*')))
154 ) && !$finished) {
155 break;
158 // Comments
159 if ($ch == '#'
160 || ($i < ($len - 1) && $ch == '-' && $buffer[$i + 1] == '-' && (($i < ($len - 2) && $buffer[$i + 2] <= ' ') || ($i == ($len - 1) && $finished)))
161 || ($i < ($len - 1) && $ch == '/' && $buffer[$i + 1] == '*')
163 // Copy current string to SQL
164 if ($start_pos != $i) {
165 $sql .= substr($buffer, $start_pos, $i - $start_pos);
167 // Skip the rest
168 $j = $i;
169 $i = strpos($buffer, $ch == '/' ? '*/' : "\n", $i);
170 // didn't we hit end of string?
171 if ($i === FALSE) {
172 if ($finished) {
173 $i = $len - 1;
174 } else {
175 break;
178 // Skip *
179 if ($ch == '/') {
180 // Check for MySQL conditional comments and include them as-is
181 if ($buffer[$j + 2] == '!') {
182 $comment = substr($buffer, $j + 3, $i - $j - 3);
183 if (preg_match('/^[0-9]{5}/', $comment, $version)) {
184 if ($version[0] <= PMA_MYSQL_INT_VERSION) {
185 $sql .= substr($comment, 5);
187 } else {
188 $sql .= $comment;
191 $i++;
193 // Skip last char
194 $i++;
195 // Next query part will start here
196 $start_pos = $i;
197 // Aren't we at the end?
198 if ($i == $len) {
199 $i--;
200 } else {
201 continue;
205 // End of SQL
206 if ($found_delimiter || ($finished && ($i == $len - 1))) {
207 $tmp_sql = $sql;
208 if ($start_pos < $len) {
209 $length_to_grab = $i - $start_pos;
210 if (!$found_delimiter) {
211 $length_to_grab++;
213 $tmp_sql .= substr($buffer, $start_pos, $length_to_grab);
214 unset($length_to_grab);
216 // Do not try to execute empty SQL
217 if (!preg_match('/^([\s]*;)*$/', trim($tmp_sql))) {
218 $sql = $tmp_sql;
219 PMA_importRunQuery($sql, substr($buffer, 0, $i + strlen($sql_delimiter)));
220 $buffer = substr($buffer, $i + strlen($sql_delimiter));
221 // Reset parser:
222 $len = strlen($buffer);
223 $sql = '';
224 $i = 0;
225 $start_pos = 0;
226 // Any chance we will get a complete query?
227 //if ((strpos($buffer, ';') === FALSE) && !$finished) {
228 if ((strpos($buffer, $sql_delimiter) === FALSE) && !$finished) {
229 break;
231 } else {
232 $i++;
233 $start_pos = $i;
236 } // End of parser loop
237 } // End of import loop
238 // Commit any possible data in buffers
239 PMA_importRunQuery('', substr($buffer, 0, $len));
240 PMA_importRunQuery();