250 |
kaklik |
1 |
<?php |
|
|
2 |
/* $Id: import.lib.php,v 1.9 2006/01/19 15:39:29 cybot_tm Exp $ */ |
|
|
3 |
// vim: expandtab sw=4 ts=4 sts=4: |
|
|
4 |
|
|
|
5 |
/* Library that provides common import functions that are used by import plugins */ |
|
|
6 |
|
|
|
7 |
// We need to know something about user |
|
|
8 |
require_once('./libraries/check_user_privileges.lib.php'); |
|
|
9 |
// We do this check |
|
|
10 |
define('PMA_CHK_DROP', 1); |
|
|
11 |
|
|
|
12 |
/** |
|
|
13 |
* Check whether timeout is getting close |
|
|
14 |
* |
|
|
15 |
* @return boolean true if timeout is close |
|
|
16 |
* @access public |
|
|
17 |
*/ |
|
|
18 |
function PMA_checkTimeout() |
|
|
19 |
{ |
|
|
20 |
global $timestamp, $maximum_time, $timeout_passed; |
|
|
21 |
if ($maximum_time == 0) { |
|
|
22 |
return FALSE; |
|
|
23 |
} elseif ($timeout_passed) { |
|
|
24 |
return TRUE; |
|
|
25 |
/* 5 in next row might be too much */ |
|
|
26 |
} elseif ((time() - $timestamp) > ($maximum_time - 5)) { |
|
|
27 |
$timeout_passed = TRUE; |
|
|
28 |
return TRUE; |
|
|
29 |
} else { |
|
|
30 |
return FALSE; |
|
|
31 |
} |
|
|
32 |
} |
|
|
33 |
|
|
|
34 |
/** |
|
|
35 |
* Detects what compression filse uses |
|
|
36 |
* |
|
|
37 |
* @param string filename to check |
|
|
38 |
* @return string MIME type of compression, none for none |
|
|
39 |
* @access public |
|
|
40 |
*/ |
|
|
41 |
function PMA_detectCompression($filepath) |
|
|
42 |
{ |
|
|
43 |
$file = @fopen($filepath, 'rb'); |
|
|
44 |
if (!$file) { |
|
|
45 |
return FALSE; |
|
|
46 |
} |
|
|
47 |
$test = fread($file, 4); |
|
|
48 |
fclose($file); |
|
|
49 |
if ($test[0] == chr(31) && $test[1] == chr(139)) { |
|
|
50 |
return 'application/gzip'; |
|
|
51 |
} |
|
|
52 |
if (substr($test, 0, 3) == 'BZh') { |
|
|
53 |
return 'application/bzip2'; |
|
|
54 |
} |
|
|
55 |
if ($test == "PK\003\004") { |
|
|
56 |
return 'application/zip'; |
|
|
57 |
} |
|
|
58 |
return 'none'; |
|
|
59 |
} |
|
|
60 |
|
|
|
61 |
/** |
|
|
62 |
* Runs query inside import buffer. This is needed to allow displaying |
|
|
63 |
* of last SELECT or SHOW results and simmilar nice stuff. |
|
|
64 |
* |
|
|
65 |
* @param string query to run |
|
|
66 |
* @param string query to display, this might be commented |
|
|
67 |
* @access public |
|
|
68 |
*/ |
|
|
69 |
function PMA_importRunQuery($sql = '', $full = '') |
|
|
70 |
{ |
|
|
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; |
|
|
72 |
$read_multiply = 1; |
|
|
73 |
if (isset($import_run_buffer)) { |
|
|
74 |
// Should we skip something? |
|
|
75 |
if ($skip_queries > 0) { |
|
|
76 |
$skip_queries--; |
|
|
77 |
} else { |
|
|
78 |
if (!empty($import_run_buffer['sql']) && trim($import_run_buffer['sql']) != '') { |
|
|
79 |
if (!$cfg['AllowUserDropDatabase'] |
|
|
80 |
&& !$is_superuser |
|
|
81 |
&& preg_match('@DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) { |
|
|
82 |
$message = $GLOBALS['strNoDropDatabases']; |
|
|
83 |
$show_error_header = TRUE; |
|
|
84 |
$error = TRUE; |
|
|
85 |
return; |
|
|
86 |
} |
|
|
87 |
$max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql'])); |
|
|
88 |
if (!$sql_query_disabled) { |
|
|
89 |
$sql_query .= $import_run_buffer['full']; |
|
|
90 |
} |
|
|
91 |
$executed_queries++; |
|
|
92 |
if ($run_query && $finished && empty($sql) && !$error && ( |
|
|
93 |
(!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW)/i', $import_run_buffer['sql'])) || |
|
|
94 |
($executed_queries == 1) |
|
|
95 |
)) { |
|
|
96 |
$go_sql = TRUE; |
|
|
97 |
if (!$sql_query_disabled) { |
|
|
98 |
$complete_query = $sql_query; |
|
|
99 |
$display_query = $sql_query; |
|
|
100 |
} else { |
|
|
101 |
$complete_query = ''; |
|
|
102 |
$display_query = ''; |
|
|
103 |
} |
|
|
104 |
$sql_query = $import_run_buffer['sql']; |
|
|
105 |
} elseif ($run_query) { |
|
|
106 |
$result = PMA_DBI_try_query($import_run_buffer['sql']); |
|
|
107 |
$msg = '# '; |
|
|
108 |
if ($result === FALSE) { // execution failed |
|
|
109 |
if (!isset($my_die)) { |
|
|
110 |
$my_die = array(); |
|
|
111 |
} |
|
|
112 |
$my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError()); |
|
|
113 |
|
|
|
114 |
if ($cfg['VerboseMultiSubmit']) { |
|
|
115 |
$msg .= $GLOBALS['strError']; |
|
|
116 |
} |
|
|
117 |
|
|
|
118 |
if (!$cfg['IgnoreMultiSubmitErrors']) { |
|
|
119 |
$error = TRUE; |
|
|
120 |
return; |
|
|
121 |
} |
|
|
122 |
} elseif ($cfg['VerboseMultiSubmit']) { |
|
|
123 |
$a_num_rows = (int)@PMA_DBI_num_rows($result); |
|
|
124 |
$a_aff_rows = (int)@PMA_DBI_affected_rows(); |
|
|
125 |
if ($a_num_rows > 0) { |
|
|
126 |
$msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows; |
|
|
127 |
} elseif ($a_aff_rows > 0) { |
|
|
128 |
$a_rows = |
|
|
129 |
$msg .= $GLOBALS['strAffectedRows'] . ' ' . $a_aff_rows; |
|
|
130 |
} else { |
|
|
131 |
$msg .= $GLOBALS['strEmptyResultSet']; |
|
|
132 |
} |
|
|
133 |
} |
|
|
134 |
if (!$sql_query_disabled) { |
|
|
135 |
$sql_query .= $msg . "\n"; |
|
|
136 |
} |
|
|
137 |
|
|
|
138 |
// If a 'USE <db>' SQL-clause was found and the query succeeded, set our current $db to the new one |
|
|
139 |
if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) { |
|
|
140 |
$db = trim($match[1]); |
|
|
141 |
$reload = TRUE; |
|
|
142 |
} |
|
|
143 |
|
|
|
144 |
if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) { |
|
|
145 |
$reload = TRUE; |
|
|
146 |
} |
|
|
147 |
} // end run query |
|
|
148 |
} // end non empty query |
|
|
149 |
elseif (!empty($import_run_buffer['full'])) { |
|
|
150 |
if ($go_sql) { |
|
|
151 |
$complete_query .= $import_run_buffer['full']; |
|
|
152 |
$display_query .= $import_run_buffer['full']; |
|
|
153 |
} else { |
|
|
154 |
if (!$sql_query_disabled) { |
|
|
155 |
$sql_query .= $import_run_buffer['full']; |
|
|
156 |
} |
|
|
157 |
} |
|
|
158 |
} |
|
|
159 |
// check length of query unless we decided to pass it to sql.php |
|
|
160 |
if (!$go_sql) { |
|
|
161 |
if ($cfg['VerboseMultiSubmit'] && !empty($sql_query)) { |
|
|
162 |
if (strlen($sql_query) > 50000 || $executed_queries > 50 || $max_sql_len > 1000) { |
|
|
163 |
$sql_query = ''; |
|
|
164 |
$sql_query_disabled = TRUE; |
|
|
165 |
} |
|
|
166 |
} else { |
|
|
167 |
if (strlen($sql_query) > 10000 || $executed_queries > 10 || $max_sql_len > 500) { |
|
|
168 |
$sql_query = ''; |
|
|
169 |
$sql_query_disabled = TRUE; |
|
|
170 |
} |
|
|
171 |
} |
|
|
172 |
} |
|
|
173 |
} // end do query (no skip) |
|
|
174 |
} // end buffer exists |
|
|
175 |
|
|
|
176 |
// Do we have something to push into buffer? |
|
|
177 |
if (!empty($sql) || !empty($full)) { |
|
|
178 |
$import_run_buffer = array('sql' => $sql, 'full' => $full); |
|
|
179 |
} else { |
|
|
180 |
unset($GLOBALS['import_run_buffer']); |
|
|
181 |
} |
|
|
182 |
} |
|
|
183 |
|
|
|
184 |
|
|
|
185 |
/** |
|
|
186 |
* Returns next part of imported file/buffer |
|
|
187 |
* |
|
|
188 |
* @param integer size of buffer to read (this is maximal size |
|
|
189 |
* function will return) |
|
|
190 |
* @return string part of file/buffer |
|
|
191 |
* @access public |
|
|
192 |
*/ |
|
|
193 |
function PMA_importGetNextChunk($size = 32768) |
|
|
194 |
{ |
|
|
195 |
global $import_file, $import_text, $finished, $compression, $import_handle, $offset, $charset_conversion, $charset_of_file, $charset, $read_multiply, $read_limit; |
|
|
196 |
|
|
|
197 |
// Add some progression while reading large amount of data |
|
|
198 |
if ($read_multiply <= 8) { |
|
|
199 |
$size *= $read_multiply; |
|
|
200 |
} else { |
|
|
201 |
$size *= 8; |
|
|
202 |
} |
|
|
203 |
$read_multiply++; |
|
|
204 |
|
|
|
205 |
// We can not read too much |
|
|
206 |
if ($size > $read_limit) { |
|
|
207 |
$size = $read_limit; |
|
|
208 |
} |
|
|
209 |
|
|
|
210 |
if (PMA_checkTimeout()) { |
|
|
211 |
return FALSE; |
|
|
212 |
} |
|
|
213 |
if ($finished) { |
|
|
214 |
return TRUE; |
|
|
215 |
} |
|
|
216 |
|
|
|
217 |
if ($import_file == 'none') { |
|
|
218 |
// Well this is not yet supported and tested, but should return content of textarea |
|
|
219 |
if (strlen($import_text) < $size) { |
|
|
220 |
$finished = TRUE; |
|
|
221 |
return $import_text; |
|
|
222 |
} else { |
|
|
223 |
$r = substr($import_text, 0, $size); |
|
|
224 |
$offset += $size; |
|
|
225 |
$import_text = substr($import_text, $size); |
|
|
226 |
return $r; |
|
|
227 |
} |
|
|
228 |
} |
|
|
229 |
|
|
|
230 |
switch ($compression) { |
|
|
231 |
case 'application/bzip2': |
|
|
232 |
$result = bzread($import_handle, $size); |
|
|
233 |
$finished = feof($import_handle); |
|
|
234 |
break; |
|
|
235 |
case 'application/gzip': |
|
|
236 |
$result = gzread($import_handle, $size); |
|
|
237 |
$finished = feof($import_handle); |
|
|
238 |
break; |
|
|
239 |
case 'application/zip': |
|
|
240 |
$result = substr($import_text, 0, $size); |
|
|
241 |
$import_text = substr($import_text, $size); |
|
|
242 |
$finished = empty($import_text); |
|
|
243 |
break; |
|
|
244 |
case 'none': |
|
|
245 |
$result = fread($import_handle, $size); |
|
|
246 |
$finished = feof($import_handle); |
|
|
247 |
break; |
|
|
248 |
} |
|
|
249 |
$offset += $size; |
|
|
250 |
|
|
|
251 |
if ($charset_conversion) { |
|
|
252 |
return PMA_convert_string($charset_of_file, $charset, $result); |
|
|
253 |
} else { |
|
|
254 |
return $result; |
|
|
255 |
} |
|
|
256 |
} |
|
|
257 |
|
|
|
258 |
|
|
|
259 |
|
|
|
260 |
?> |