3 // vim: expandtab sw=4 ts=4 sts=4:
5 /* Library that provides common import functions that are used by import plugins */
7 // We need to know something about user
8 require_once('./libraries/check_user_privileges.lib.php');
10 define('PMA_CHK_DROP', 1);
13 * Check whether timeout is getting close
15 * @return boolean true if timeout is close
18 function PMA_checkTimeout()
20 global $timestamp, $maximum_time, $timeout_passed;
21 if ($maximum_time == 0) {
23 } elseif ($timeout_passed) {
25 /* 5 in next row might be too much */
26 } elseif ((time() - $timestamp) > ($maximum_time - 5)) {
27 $timeout_passed = TRUE;
35 * Detects what compression filse uses
37 * @param string filename to check
38 * @return string MIME type of compression, none for none
41 function PMA_detectCompression($filepath)
43 $file = @fopen
($filepath, 'rb');
47 $test = fread($file, 4);
49 if ($test[0] == chr(31) && $test[1] == chr(139)) {
50 return 'application/gzip';
52 if (substr($test, 0, 3) == 'BZh') {
53 return 'application/bzip2';
55 if ($test == "PK\003\004") {
56 return 'application/zip';
62 * Runs query inside import buffer. This is needed to allow displaying
63 * of last SELECT, SHOW or HANDLER results and similar nice stuff.
65 * @param string query to run
66 * @param string query to display, this might be commented
69 function PMA_importRunQuery($sql = '', $full = '')
71 global $import_run_buffer, $go_sql, $complete_query, $display_query, $sql_query, $cfg, $my_die, $error, $reload, $finished, $timeout_passed, $skip_queries, $executed_queries, $max_sql_len, $read_multiply, $cfg, $sql_query_disabled, $db, $run_query, $is_superuser, $message, $show_error_header;
73 if (isset($import_run_buffer)) {
74 // Should we skip something?
75 if ($skip_queries > 0) {
78 if (!empty($import_run_buffer['sql']) && trim($import_run_buffer['sql']) != '') {
79 $max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql']));
80 if (!$sql_query_disabled) {
81 $sql_query .= $import_run_buffer['full'];
83 if (!$cfg['AllowUserDropDatabase']
85 && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) {
86 $message = $GLOBALS['strNoDropDatabases'];
87 $show_error_header = TRUE;
91 if ($run_query && $finished && empty($sql) && !$error && (
92 (!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW|HANDLER)/i', $import_run_buffer['sql'])) ||
93 ($executed_queries == 1)
96 if (!$sql_query_disabled) {
97 $complete_query = $sql_query;
98 $display_query = $sql_query;
100 $complete_query = '';
103 $sql_query = $import_run_buffer['sql'];
104 } elseif ($run_query) {
105 $result = PMA_DBI_try_query($import_run_buffer['sql']);
107 if ($result === FALSE) { // execution failed
108 if (!isset($my_die)) {
111 $my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError());
113 if ($cfg['VerboseMultiSubmit']) {
114 $msg .= $GLOBALS['strError'];
117 if (!$cfg['IgnoreMultiSubmitErrors']) {
121 } elseif ($cfg['VerboseMultiSubmit']) {
122 $a_num_rows = (int)@PMA_DBI_num_rows
($result);
123 $a_aff_rows = (int)@PMA_DBI_affected_rows
();
124 if ($a_num_rows > 0) {
125 $msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows;
126 } elseif ($a_aff_rows > 0) {
128 $msg .= $GLOBALS['strAffectedRows'] . ' ' . $a_aff_rows;
130 $msg .= $GLOBALS['strEmptyResultSet'];
133 if (!$sql_query_disabled) {
134 $sql_query .= $msg . "\n";
137 // If a 'USE <db>' SQL-clause was found and the query succeeded, set our current $db to the new one
138 if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) {
139 $db = trim($match[1]);
140 $db = trim($db,';'); // for example, USE abc;
144 if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) {
148 } // end if not DROP DATABASE
149 } // end non empty query
150 elseif (!empty($import_run_buffer['full'])) {
152 $complete_query .= $import_run_buffer['full'];
153 $display_query .= $import_run_buffer['full'];
155 if (!$sql_query_disabled) {
156 $sql_query .= $import_run_buffer['full'];
160 // check length of query unless we decided to pass it to sql.php
162 if ($cfg['VerboseMultiSubmit'] && !empty($sql_query)) {
163 if (strlen($sql_query) > 50000 ||
$executed_queries > 50 ||
$max_sql_len > 1000) {
165 $sql_query_disabled = TRUE;
168 if (strlen($sql_query) > 10000 ||
$executed_queries > 10 ||
$max_sql_len > 500) {
170 $sql_query_disabled = TRUE;
174 } // end do query (no skip)
175 } // end buffer exists
177 // Do we have something to push into buffer?
178 if (!empty($sql) ||
!empty($full)) {
179 $import_run_buffer = array('sql' => $sql, 'full' => $full);
181 unset($GLOBALS['import_run_buffer']);
187 * Returns next part of imported file/buffer
189 * @param integer size of buffer to read (this is maximal size
190 * function will return)
191 * @return string part of file/buffer
194 function PMA_importGetNextChunk($size = 32768)
196 global $import_file, $import_text, $finished, $compression, $import_handle, $offset, $charset_conversion, $charset_of_file, $charset, $read_multiply, $read_limit;
198 // Add some progression while reading large amount of data
199 if ($read_multiply <= 8) {
200 $size *= $read_multiply;
206 // We can not read too much
207 if ($size > $read_limit) {
211 if (PMA_checkTimeout()) {
218 if ($import_file == 'none') {
219 // Well this is not yet supported and tested, but should return content of textarea
220 if (strlen($import_text) < $size) {
224 $r = substr($import_text, 0, $size);
226 $import_text = substr($import_text, $size);
231 switch ($compression) {
232 case 'application/bzip2':
233 $result = bzread($import_handle, $size);
234 $finished = feof($import_handle);
236 case 'application/gzip':
237 $result = gzread($import_handle, $size);
238 $finished = feof($import_handle);
240 case 'application/zip':
241 $result = substr($import_text, 0, $size);
242 $import_text = substr($import_text, $size);
243 $finished = empty($import_text);
246 $result = fread($import_handle, $size);
247 $finished = feof($import_handle);
252 if ($charset_conversion) {
253 return PMA_convert_string($charset_of_file, $charset, $result);
255 // Skip possible byte order marks (I do not think we need more
256 // charsets, but feel free to add more, you can use wikipedia for
257 // reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
258 // @TODO: BOM could be used for charset autodetection
259 if ($offset == $size) {
261 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
262 $result = substr($result, 3);
264 } elseif (strncmp($result, "\xFE\xFF", 2) == 0 ||
strncmp($result, "\xFF\xFE", 2) == 0) {
265 $result = substr($result, 2);