Rev Author Line No. Line
250 kaklik 1 <?php
2 /* $Id: tbl_move_copy.php,v 1.12 2006/01/17 17:02:31 cybot_tm Exp $ */
3 // vim: expandtab sw=4 ts=4 sts=4:
4  
5 /**
6 * Inserts existing entries in a PMA_* table by reading a value from an old entry
7 *
8 * @param string The array index, which Relation feature to check
9 * ('relwork', 'commwork', ...)
10 * @param string The array index, which PMA-table to update
11 * ('bookmark', 'relation', ...)
12 * @param array Which fields will be SELECT'ed from the old entry
13 * @param array Which fields will be used for the WHERE query
14 * (array('FIELDNAME' => 'FIELDVALUE'))
15 * @param array Which fields will be used as new VALUES. These are the important
16 * keys which differ from the old entry.
17 * (array('FIELDNAME' => 'NEW FIELDVALUE'))
18  
19 * @global string relation variable
20 *
21 * @author Garvin Hicking <me@supergarv.de>
22 */
23 function PMA_duplicate_table_info($work, $pma_table, $get_fields, $where_fields, $new_fields) {
24 global $cfgRelation;
25  
26 $last_id = -1;
27  
28 if ($cfgRelation[$work]) {
29 $select_parts = array();
30 $row_fields = array();
31 foreach ($get_fields AS $nr => $get_field) {
32 $select_parts[] = PMA_backquote($get_field);
33 $row_fields[$get_field] = 'cc';
34 }
35  
36 $where_parts = array();
37 foreach ($where_fields AS $_where => $_value) {
38 $where_parts[] = PMA_backquote($_where) . ' = \'' . PMA_sqlAddslashes($_value) . '\'';
39 }
40  
41 $new_parts = array();
42 $new_value_parts = array();
43 foreach ($new_fields AS $_where => $_value) {
44 $new_parts[] = PMA_backquote($_where);
45 $new_value_parts[] = PMA_sqlAddslashes($_value);
46 }
47  
48 $table_copy_query = 'SELECT ' . implode(', ', $select_parts)
49 . ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation[$pma_table])
50 . ' WHERE ' . implode(' AND ', $where_parts);
51  
52 // must use PMA_DBI_QUERY_STORE here, since we execute another
53 // query inside the loop
54 $table_copy_rs = PMA_query_as_cu($table_copy_query, TRUE, PMA_DBI_QUERY_STORE);
55  
56 while ($table_copy_row = @PMA_DBI_fetch_assoc($table_copy_rs)) {
57 $value_parts = array();
58 foreach ($table_copy_row AS $_key => $_val) {
59 if (isset($row_fields[$_key]) && $row_fields[$_key] == 'cc') {
60 $value_parts[] = PMA_sqlAddslashes($_val);
61 }
62 }
63  
64 $new_table_query = 'INSERT IGNORE INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation[$pma_table])
65 . ' (' . implode(', ', $select_parts) . ', ' . implode(', ', $new_parts) . ')'
66 . ' VALUES '
67 . ' (\'' . implode('\', \'', $value_parts) . '\', \'' . implode('\', \'', $new_value_parts) . '\')';
68  
69 $new_table_rs = PMA_query_as_cu($new_table_query);
70 $last_id = PMA_DBI_insert_id();
71 } // end while
72  
73 return $last_id;
74 }
75  
76 return true;
77 } // end of 'PMA_duplicate_table_info()' function
78  
79  
80 /**
81 * Copies or renames table
82 * FIXME: use RENAME
83 *
84 * @author Michal Čihař <michal@cihar.com>
85 */
86 function PMA_table_move_copy($source_db, $source_table, $target_db, $target_table, $what, $move) {
87 global $cfgRelation, $dblist, $err_url, $sql_query;
88  
89 // set export settings we need
90 $GLOBALS['use_backquotes'] = 1;
91 $GLOBALS['asfile'] = 1;
92  
93 // Ensure the target is valid
94 if ( count($dblist) > 0 &&
95 ( ! in_array($source_db, $dblist) || ! in_array($target_db, $dblist) )) {
96 exit();
97 }
98  
99 $source = PMA_backquote($source_db) . '.' . PMA_backquote($source_table);
100 if ( ! isset($target_db) || ! strlen($target_db) ) {
101 $target_db = $source_db;
102 }
103  
104 // Doing a select_db could avoid some problems with replicated databases,
105 // when moving table from replicated one to not replicated one
106 PMA_DBI_select_db($target_db);
107  
108 $target = PMA_backquote($target_db) . '.' . PMA_backquote($target_table);
109  
110 // do not create the table if dataonly
111 if ($what != 'dataonly') {
112 require_once('./libraries/export/sql.php');
113  
114 $no_constraints_comments = true;
115 $sql_structure = PMA_getTableDef($source_db, $source_table, "\n", $err_url);
116 unset($no_constraints_comments);
117  
118 $parsed_sql = PMA_SQP_parse($sql_structure);
119  
120 /* nijel: Find table name in query and replace it */
121 $i = 0;
122 while ($parsed_sql[$i]['type'] != 'quote_backtick') $i++;
123  
124 /* no need to PMA_backquote() */
125 $parsed_sql[$i]['data'] = $target;
126  
127 /* Generate query back */
128 $sql_structure = PMA_SQP_formatHtml($parsed_sql, 'query_only');
129 // If table exists, and 'add drop table' is selected: Drop it!
130 $drop_query = '';
131 if (isset($GLOBALS['drop_if_exists']) && $GLOBALS['drop_if_exists'] == 'true') {
132 $drop_query = 'DROP TABLE IF EXISTS ' . PMA_backquote($target_db) . '.' . PMA_backquote($target_table);
133 $result = PMA_DBI_query($drop_query);
134  
135 if (isset($sql_query)) {
136 $sql_query .= "\n" . $drop_query . ';';
137 } else {
138 $sql_query = $drop_query . ';';
139 }
140  
141 // garvin: If an existing table gets deleted, maintain any entries
142 // for the PMA_* tables
143 $maintain_relations = TRUE;
144 }
145  
146 $result = @PMA_DBI_query($sql_structure);
147 if (isset($sql_query)) {
148 $sql_query .= "\n" . $sql_structure . ';';
149 } else {
150 $sql_query = $sql_structure . ';';
151 }
152  
153 if (($move || isset($GLOBALS['constraints'])) && isset($GLOBALS['sql_constraints'])) {
154 $parsed_sql = PMA_SQP_parse($GLOBALS['sql_constraints']);
155 $i = 0;
156  
157 // find the first quote_backtick, it must be the source table name
158 while ($parsed_sql[$i]['type'] != 'quote_backtick') {
159 $i++;
160 }
161  
162 // replace it by the target table name, no need to PMA_backquote()
163 $parsed_sql[$i]['data'] = $target;
164  
165 // now we must remove all quote_backtick that follow a CONSTRAINT
166 // keyword, because a constraint name must be unique in a db
167  
168 $cnt = $parsed_sql['len'] - 1;
169  
170 for ($j = $i; $j < $cnt; $j++) {
171 if ($parsed_sql[$j]['type'] == 'alpha_reservedWord'
172 && strtoupper($parsed_sql[$j]['data']) == 'CONSTRAINT') {
173 if ($parsed_sql[$j+1]['type'] == 'quote_backtick') {
174 $parsed_sql[$j+1]['data'] = '';
175 }
176 }
177 }
178  
179  
180 // Generate query back
181 $GLOBALS['sql_constraints'] = PMA_SQP_formatHtml($parsed_sql, 'query_only');
182 $result = PMA_DBI_query($GLOBALS['sql_constraints']);
183 if (isset($sql_query)) {
184 $sql_query .= "\n" . $GLOBALS['sql_constraints'];
185 } else {
186 $sql_query = $GLOBALS['sql_constraints'];
187 }
188  
189 unset($GLOBALS['sql_constraints']);
190 }
191  
192 } else {
193 $sql_query='';
194 }
195  
196 // Copy the data
197 //if ($result != FALSE && ($what == 'data' || $what == 'dataonly')) {
198 if ($what == 'data' || $what == 'dataonly') {
199 $sql_insert_data = 'INSERT INTO ' . $target . ' SELECT * FROM ' . $source;
200 PMA_DBI_query($sql_insert_data);
201 $sql_query .= "\n\n" . $sql_insert_data . ';';
202 }
203  
204 require_once('./libraries/relation.lib.php');
205 $cfgRelation = PMA_getRelationsParam();
206  
207 // Drops old table if the user has requested to move it
208 if ($move) {
209  
210 // This could avoid some problems with replicated databases, when
211 // moving table from replicated one to not replicated one
212 PMA_DBI_select_db($source_db);
213  
214 $sql_drop_table = 'DROP TABLE ' . $source;
215 PMA_DBI_query($sql_drop_table);
216  
217 // garvin: Move old entries from PMA-DBs to new table
218 if ($cfgRelation['commwork']) {
219 $remove_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['column_info'])
220 . ' SET table_name = \'' . PMA_sqlAddslashes($target_table) . '\', '
221 . ' db_name = \'' . PMA_sqlAddslashes($target_db) . '\''
222 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\''
223 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\'';
224 $rmv_rs = PMA_query_as_cu($remove_query);
225 unset($remove_query);
226 }
227  
228 // garvin: updating bookmarks is not possible since only a single table is moved,
229 // and not the whole DB.
230 // if ($cfgRelation['bookmarkwork']) {
231 // $remove_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['bookmark'])
232 // . ' SET dbase = \'' . PMA_sqlAddslashes($target_db) . '\''
233 // . ' WHERE dbase = \'' . PMA_sqlAddslashes($source_db) . '\'';
234 // $rmv_rs = PMA_query_as_cu($remove_query);
235 // unset($rmv_query);
236 // }
237  
238 if ($cfgRelation['displaywork']) {
239 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_info'])
240 . ' SET db_name = \'' . PMA_sqlAddslashes($target_db) . '\', '
241 . ' table_name = \'' . PMA_sqlAddslashes($target_table) . '\''
242 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\''
243 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\'';
244 $tb_rs = PMA_query_as_cu($table_query);
245 unset($table_query);
246 unset($tb_rs);
247 }
248  
249 if ($cfgRelation['relwork']) {
250 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation'])
251 . ' SET foreign_table = \'' . PMA_sqlAddslashes($target_table) . '\','
252 . ' foreign_db = \'' . PMA_sqlAddslashes($target_db) . '\''
253 . ' WHERE foreign_db = \'' . PMA_sqlAddslashes($source_db) . '\''
254 . ' AND foreign_table = \'' . PMA_sqlAddslashes($source_table) . '\'';
255 $tb_rs = PMA_query_as_cu($table_query);
256 unset($table_query);
257 unset($tb_rs);
258  
259 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation'])
260 . ' SET master_table = \'' . PMA_sqlAddslashes($target_table) . '\','
261 . ' master_db = \'' . PMA_sqlAddslashes($target_db) . '\''
262 . ' WHERE master_db = \'' . PMA_sqlAddslashes($source_db) . '\''
263 . ' AND master_table = \'' . PMA_sqlAddslashes($source_table) . '\'';
264 $tb_rs = PMA_query_as_cu($table_query);
265 unset($table_query);
266 unset($tb_rs);
267 }
268  
269 // garvin: [TODO] Can't get moving PDFs the right way. The page numbers always
270 // get screwed up independently from duplication because the numbers do not
271 // seem to be stored on a per-database basis. Would the author of pdf support
272 // please have a look at it?
273  
274 if ($cfgRelation['pdfwork']) {
275 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
276 . ' SET table_name = \'' . PMA_sqlAddslashes($target_table) . '\','
277 . ' db_name = \'' . PMA_sqlAddslashes($target_db) . '\''
278 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\''
279 . ' AND table_name = \'' . PMA_sqlAddslashes($source_table) . '\'';
280 $tb_rs = PMA_query_as_cu($table_query);
281 unset($table_query);
282 unset($tb_rs);
283 /*
284 $pdf_query = 'SELECT pdf_page_number '
285 . ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
286 . ' WHERE db_name = \'' . PMA_sqlAddslashes($target_db) . '\''
287 . ' AND table_name = \'' . PMA_sqlAddslashes($target_table) . '\'';
288 $pdf_rs = PMA_query_as_cu($pdf_query);
289  
290 while ($pdf_copy_row = PMA_DBI_fetch_assoc($pdf_rs)) {
291 $table_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
292 . ' SET db_name = \'' . PMA_sqlAddslashes($target_db) . '\''
293 . ' WHERE db_name = \'' . PMA_sqlAddslashes($source_db) . '\''
294 . ' AND page_nr = \'' . PMA_sqlAddslashes($pdf_copy_row['pdf_page_number']) . '\'';
295 $tb_rs = PMA_query_as_cu($table_query);
296 unset($table_query);
297 unset($tb_rs);
298 }
299 */
300 }
301  
302 $sql_query .= "\n\n" . $sql_drop_table . ';';
303 } else {
304 // garvin: Create new entries as duplicates from old PMA DBs
305 if ($what != 'dataonly' && !isset($maintain_relations)) {
306 if ($cfgRelation['commwork']) {
307 // Get all comments and MIME-Types for current table
308 $comments_copy_query = 'SELECT
309 column_name, ' . PMA_backquote('comment') . ($cfgRelation['mimework'] ? ', mimetype, transformation, transformation_options' : '') . '
310 FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
311 WHERE
312 db_name = \'' . PMA_sqlAddslashes($source_db) . '\' AND
313 table_name = \'' . PMA_sqlAddslashes($source_table) . '\'';
314 $comments_copy_rs = PMA_query_as_cu($comments_copy_query);
315  
316 // Write every comment as new copied entry. [MIME]
317 while ($comments_copy_row = PMA_DBI_fetch_assoc($comments_copy_rs)) {
318 $new_comment_query = 'REPLACE INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['column_info'])
319 . ' (db_name, table_name, column_name, ' . PMA_backquote('comment') . ($cfgRelation['mimework'] ? ', mimetype, transformation, transformation_options' : '') . ') '
320 . ' VALUES('
321 . '\'' . PMA_sqlAddslashes($target_db) . '\','
322 . '\'' . PMA_sqlAddslashes($target_table) . '\','
323 . '\'' . PMA_sqlAddslashes($comments_copy_row['column_name']) . '\''
324 . ($cfgRelation['mimework'] ? ',\'' . PMA_sqlAddslashes($comments_copy_row['comment']) . '\','
325 . '\'' . PMA_sqlAddslashes($comments_copy_row['mimetype']) . '\','
326 . '\'' . PMA_sqlAddslashes($comments_copy_row['transformation']) . '\','
327 . '\'' . PMA_sqlAddslashes($comments_copy_row['transformation_options']) . '\'' : '')
328 . ')';
329 $new_comment_rs = PMA_query_as_cu($new_comment_query);
330 } // end while
331 }
332  
333 // duplicating the bookmarks must not be done here, but
334 // just once per db
335  
336 $get_fields = array('display_field');
337 $where_fields = array('db_name' => $source_db, 'table_name' => $source_table);
338 $new_fields = array('db_name' => $target_db, 'table_name' => $target_table);
339 PMA_duplicate_table_info('displaywork', 'table_info', $get_fields, $where_fields, $new_fields);
340  
341 $get_fields = array('master_field', 'foreign_db', 'foreign_table', 'foreign_field');
342 $where_fields = array('master_db' => $source_db, 'master_table' => $source_table);
343 $new_fields = array('master_db' => $target_db, 'master_table' => $target_table);
344 PMA_duplicate_table_info('relwork', 'relation', $get_fields, $where_fields, $new_fields);
345  
346 $get_fields = array('foreign_field', 'master_db', 'master_table', 'master_field');
347 $where_fields = array('foreign_db' => $source_db, 'foreign_table' => $source_table);
348 $new_fields = array('foreign_db' => $target_db, 'foreign_table' => $target_table);
349 PMA_duplicate_table_info('relwork', 'relation', $get_fields, $where_fields, $new_fields);
350  
351 // garvin: [TODO] Can't get duplicating PDFs the right way. The page numbers always
352 // get screwed up independently from duplication because the numbers do not
353 // seem to be stored on a per-database basis. Would the author of pdf support
354 // please have a look at it?
355 /*
356 $get_fields = array('page_descr');
357 $where_fields = array('db_name' => $source_db);
358 $new_fields = array('db_name' => $target_db);
359 $last_id = PMA_duplicate_table_info('pdfwork', 'pdf_pages', $get_fields, $where_fields, $new_fields);
360  
361 if (isset($last_id) && $last_id >= 0) {
362 $get_fields = array('x', 'y');
363 $where_fields = array('db_name' => $source_db, 'table_name' => $source_table);
364 $new_fields = array('db_name' => $target_db, 'table_name' => $target_table, 'pdf_page_number' => $last_id);
365 PMA_duplicate_table_info('pdfwork', 'table_coords', $get_fields, $where_fields, $new_fields);
366 }
367 */
368 }
369 }
370  
371 }
372  
373 /**
374 * renames table
375 *
376 * @param string old tbale name
377 * @param string new table name
378 * @return boolean success
379 */
380 function PMA_table_rename( $old_name, $new_name )
381 {
382 // Ensure the target is valid
383 if ( count($GLOBALS['dblist']) > 0
384 && ! in_array($GLOBALS['db'], $GLOBALS['dblist']) ) {
385 return false;
386 }
387  
388 PMA_DBI_select_db($GLOBALS['db']);
389  
390 $sql_query = '
391 ALTER TABLE ' . PMA_backquote($old_name) . '
392 RENAME ' . PMA_backquote($new_name) . ';';
393 if ( ! PMA_DBI_query($sql_query) ) {
394 return false;
395 }
396  
397 // garvin: Move old entries from comments to new table
398 require_once('./libraries/relation.lib.php');
399 $cfgRelation = PMA_getRelationsParam();
400 if ( $cfgRelation['commwork'] ) {
401 $remove_query = '
402 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
403 SET table_name = \'' . PMA_sqlAddslashes($new_name) . '\'
404 WHERE db_name = \'' . PMA_sqlAddslashes($GLOBALS['db']) . '\'
405 AND table_name = \'' . PMA_sqlAddslashes($old_name) . '\'';
406 PMA_query_as_cu($remove_query);
407 unset($remove_query);
408 }
409  
410 if ( $cfgRelation['displaywork'] ) {
411 $table_query = '
412 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_info']) . '
413 SET table_name = \'' . PMA_sqlAddslashes($new_name) . '\'
414 WHERE db_name = \'' . PMA_sqlAddslashes($GLOBALS['db']) . '\'
415 AND table_name = \'' . PMA_sqlAddslashes($old_name) . '\'';
416 PMA_query_as_cu($table_query);
417 unset($table_query);
418 }
419  
420 if ( $cfgRelation['relwork'] ) {
421 $table_query = '
422 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation']) . '
423 SET foreign_table = \'' . PMA_sqlAddslashes($new_name) . '\'
424 WHERE foreign_db = \'' . PMA_sqlAddslashes($GLOBALS['db']) . '\'
425 AND foreign_table = \'' . PMA_sqlAddslashes($old_name) . '\'';
426 PMA_query_as_cu($table_query);
427  
428 $table_query = '
429 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation']) . '
430 SET master_table = \'' . PMA_sqlAddslashes($new_name) . '\'
431 WHERE master_db = \'' . PMA_sqlAddslashes($GLOBALS['db']) . '\'
432 AND master_table = \'' . PMA_sqlAddslashes($old_name) . '\'';
433 PMA_query_as_cu($table_query);
434 unset($table_query);
435 }
436  
437 if ( $cfgRelation['pdfwork'] ) {
438 $table_query = '
439 UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . '
440 SET table_name = \'' . PMA_sqlAddslashes($new_name) . '\'
441 WHERE db_name = \'' . PMA_sqlAddslashes($GLOBALS['db']) . '\'
442 AND table_name = \'' . PMA_sqlAddslashes($old_name) . '\'';
443 PMA_query_as_cu($table_query);
444 unset($table_query);
445 }
446  
447 return true;
448 }
449 ?>