2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Library that provides common import functions that are used by import plugins
10 * We need to know something about user
12 require_once './libraries/check_user_privileges.lib.php';
15 * We do this check, DROP DATABASE does not need to be confirmed elsewhere
17 define('PMA_CHK_DROP', 1);
20 * Check whether timeout is getting close
22 * @return boolean true if timeout is close
25 function PMA_checkTimeout()
27 global $timestamp, $maximum_time, $timeout_passed;
28 if ($maximum_time == 0) {
30 } elseif ($timeout_passed) {
32 /* 5 in next row might be too much */
33 } elseif ((time() - $timestamp) > ($maximum_time - 5)) {
34 $timeout_passed = TRUE;
42 * Detects what compression filse uses
44 * @param string filename to check
45 * @return string MIME type of compression, none for none
48 function PMA_detectCompression($filepath)
50 $file = @fopen
($filepath, 'rb');
54 $test = fread($file, 4);
57 if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
58 return 'application/gzip';
60 if ($len >= 3 && substr($test, 0, 3) == 'BZh') {
61 return 'application/bzip2';
63 if ($len >= 4 && $test == "PK\003\004") {
64 return 'application/zip';
70 * Runs query inside import buffer. This is needed to allow displaying
71 * of last SELECT, SHOW or HANDLER results and similar nice stuff.
73 * @uses $GLOBALS['finished'] read and write
74 * @param string query to run
75 * @param string query to display, this might be commented
76 * @param bool whether to use control user for queries
79 function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
81 global $import_run_buffer, $go_sql, $complete_query, $display_query,
82 $sql_query, $cfg, $my_die, $error, $reload, $timeout_passed,
83 $skip_queries, $executed_queries, $max_sql_len, $read_multiply,
84 $cfg, $sql_query_disabled, $db, $run_query, $is_superuser;
86 if (isset($import_run_buffer)) {
87 // Should we skip something?
88 if ($skip_queries > 0) {
91 if (!empty($import_run_buffer['sql']) && trim($import_run_buffer['sql']) != '') {
92 $max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql']));
93 if (!$sql_query_disabled) {
94 $sql_query .= $import_run_buffer['full'];
96 if (!$cfg['AllowUserDropDatabase']
98 && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) {
99 $GLOBALS['message'] = PMA_Message
::error('strNoDropDatabases');
103 if ($run_query && $GLOBALS['finished'] && empty($sql) && !$error && (
104 (!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW|HANDLER)/i', $import_run_buffer['sql'])) ||
105 ($executed_queries == 1)
108 if (!$sql_query_disabled) {
109 $complete_query = $sql_query;
110 $display_query = $sql_query;
112 $complete_query = '';
115 $sql_query = $import_run_buffer['sql'];
116 } elseif ($run_query) {
118 $result = PMA_query_as_cu($import_run_buffer['sql']);
120 $result = PMA_DBI_try_query($import_run_buffer['sql']);
123 if ($result === FALSE) { // execution failed
124 if (!isset($my_die)) {
127 $my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError());
129 if ($cfg['VerboseMultiSubmit']) {
130 $msg .= $GLOBALS['strError'];
133 if (!$cfg['IgnoreMultiSubmitErrors']) {
137 } elseif ($cfg['VerboseMultiSubmit']) {
138 $a_num_rows = (int)@PMA_DBI_num_rows
($result);
139 $a_aff_rows = (int)@PMA_DBI_affected_rows
();
140 if ($a_num_rows > 0) {
141 $msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows;
142 } elseif ($a_aff_rows > 0) {
144 $msg .= sprintf($GLOBALS['strRowsAffected'], $a_aff_rows);
146 $msg .= $GLOBALS['strEmptyResultSet'];
149 if (!$sql_query_disabled) {
150 $sql_query .= $msg . "\n";
153 // If a 'USE <db>' SQL-clause was found and the query succeeded, set our current $db to the new one
154 if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) {
155 $db = trim($match[1]);
156 $db = trim($db,';'); // for example, USE abc;
160 if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) {
164 } // end if not DROP DATABASE
165 } // end non empty query
166 elseif (!empty($import_run_buffer['full'])) {
168 $complete_query .= $import_run_buffer['full'];
169 $display_query .= $import_run_buffer['full'];
171 if (!$sql_query_disabled) {
172 $sql_query .= $import_run_buffer['full'];
176 // check length of query unless we decided to pass it to sql.php
178 if ($cfg['VerboseMultiSubmit'] && ! empty($sql_query)) {
179 if (strlen($sql_query) > 50000 ||
$executed_queries > 50 ||
$max_sql_len > 1000) {
181 $sql_query_disabled = TRUE;
184 if (strlen($sql_query) > 10000 ||
$executed_queries > 10 ||
$max_sql_len > 500) {
186 $sql_query_disabled = TRUE;
190 } // end do query (no skip)
191 } // end buffer exists
193 // Do we have something to push into buffer?
194 if (!empty($sql) ||
!empty($full)) {
195 $import_run_buffer = array('sql' => $sql, 'full' => $full);
197 unset($GLOBALS['import_run_buffer']);
203 * Returns next part of imported file/buffer
205 * @uses $GLOBALS['offset'] read and write
206 * @uses $GLOBALS['import_file'] read only
207 * @uses $GLOBALS['import_text'] read and write
208 * @uses $GLOBALS['finished'] read and write
209 * @uses $GLOBALS['read_limit'] read only
210 * @param integer size of buffer to read (this is maximal size
211 * function will return)
212 * @return string part of file/buffer
215 function PMA_importGetNextChunk($size = 32768)
217 global $compression, $import_handle, $charset_conversion, $charset_of_file,
218 $charset, $read_multiply;
220 // Add some progression while reading large amount of data
221 if ($read_multiply <= 8) {
222 $size *= $read_multiply;
228 // We can not read too much
229 if ($size > $GLOBALS['read_limit']) {
230 $size = $GLOBALS['read_limit'];
233 if (PMA_checkTimeout()) {
236 if ($GLOBALS['finished']) {
240 if ($GLOBALS['import_file'] == 'none') {
241 // Well this is not yet supported and tested, but should return content of textarea
242 if (strlen($GLOBALS['import_text']) < $size) {
243 $GLOBALS['finished'] = TRUE;
244 return $GLOBALS['import_text'];
246 $r = substr($GLOBALS['import_text'], 0, $size);
247 $GLOBALS['offset'] +
= $size;
248 $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
253 switch ($compression) {
254 case 'application/bzip2':
255 $result = bzread($import_handle, $size);
256 $GLOBALS['finished'] = feof($import_handle);
258 case 'application/gzip':
259 $result = gzread($import_handle, $size);
260 $GLOBALS['finished'] = feof($import_handle);
262 case 'application/zip':
263 $result = substr($GLOBALS['import_text'], 0, $size);
264 $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
265 $GLOBALS['finished'] = empty($GLOBALS['import_text']);
268 $result = fread($import_handle, $size);
269 $GLOBALS['finished'] = feof($import_handle);
272 $GLOBALS['offset'] +
= $size;
274 if ($charset_conversion) {
275 return PMA_convert_string($charset_of_file, $charset, $result);
278 * Skip possible byte order marks (I do not think we need more
279 * charsets, but feel free to add more, you can use wikipedia for
280 * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
282 * @todo BOM could be used for charset autodetection
284 if ($GLOBALS['offset'] == $size) {
286 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
287 $result = substr($result, 3);
289 } elseif (strncmp($result, "\xFE\xFF", 2) == 0 ||
strncmp($result, "\xFF\xFE", 2) == 0) {
290 $result = substr($result, 2);