operations.lib.php 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * set of functions with the operations section in pma
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Get HTML output for database comment
  13. *
  14. * @param string $db database name
  15. *
  16. * @return string $html_output
  17. */
  18. function PMA_getHtmlForDatabaseComment($db)
  19. {
  20. $html_output = '<div class="operations_half_width">'
  21. . '<form method="post" action="db_operations.php">'
  22. . PMA_generate_common_hidden_inputs($db)
  23. . '<fieldset>'
  24. . '<legend>';
  25. if (in_array(
  26. $GLOBALS['cfg']['ActionLinksMode'],
  27. array('icons', 'both')
  28. )
  29. ) {
  30. $html_output .= '<img class="icon ic_b_comment" '
  31. . 'src="themes/dot.gif" alt="" />';
  32. }
  33. $html_output .= __('Database comment: ');
  34. $html_output .= '</legend>';
  35. $html_output .= '<input type="text" name="comment" '
  36. . 'class="textfield" size="30"'
  37. . 'value="' . htmlspecialchars(PMA_getDBComment($db)) . '" />'
  38. . '</fieldset>';
  39. $html_output .= '<fieldset class="tblFooters">'
  40. . '<input type="submit" value="' . __('Go') . '" />'
  41. . '</fieldset>'
  42. . '</form>'
  43. . '</div>';
  44. return $html_output;
  45. }
  46. /**
  47. * Get HTML output for rename database
  48. *
  49. * @param string $db database name
  50. *
  51. * @return string $html_output
  52. */
  53. function PMA_getHtmlForRenameDatabase($db)
  54. {
  55. $html_output = '<div class="operations_half_width">'
  56. . '<form id="rename_db_form" '
  57. . 'class="ajax" '
  58. . 'method="post" action="db_operations.php" '
  59. . 'onsubmit="return emptyFormElements(this, \'newname\')">';
  60. if (isset($_REQUEST['db_collation'])) {
  61. $html_output .= '<input type="hidden" name="db_collation" '
  62. . 'value="' . $_REQUEST['db_collation']
  63. .'" />' . "\n";
  64. }
  65. $html_output .= '<input type="hidden" name="what" value="data" />'
  66. . '<input type="hidden" name="db_rename" value="true" />'
  67. . PMA_generate_common_hidden_inputs($db)
  68. . '<fieldset>'
  69. . '<legend>';
  70. if (in_array(
  71. $GLOBALS['cfg']['ActionLinksMode'],
  72. array('icons', 'both')
  73. )
  74. ) {
  75. $html_output .= PMA_Util::getImage('b_edit.png');
  76. }
  77. $html_output .= __('Rename database to') . ':'
  78. . '</legend>';
  79. $html_output .= '<input id="new_db_name" type="text" name="newname" '
  80. . 'size="30" class="textfield" value="" />'
  81. . '</fieldset>'
  82. . '<fieldset class="tblFooters">'
  83. . '<input id="rename_db_input" type="submit" value="' . __('Go') . '" />'
  84. . '</fieldset>'
  85. . '</form>'
  86. . '</div>';
  87. return $html_output;
  88. }
  89. /**
  90. * Get HTML for database drop link
  91. *
  92. * @param string $db database name
  93. *
  94. * @return string $html_output
  95. */
  96. function PMA_getHtmlForDropDatabaseLink($db)
  97. {
  98. $this_sql_query = 'DROP DATABASE ' . PMA_Util::backquote($db);
  99. $this_url_params = array(
  100. 'sql_query' => $this_sql_query,
  101. 'back' => 'db_operations.php',
  102. 'goto' => 'index.php',
  103. 'reload' => '1',
  104. 'purge' => '1',
  105. 'message_to_show' => sprintf(
  106. __('Database %s has been dropped.'),
  107. htmlspecialchars(PMA_Util::backquote($db))
  108. ),
  109. 'db' => null,
  110. );
  111. $html_output = '<div class="operations_half_width">'
  112. . '<fieldset class="caution">';
  113. $html_output .= '<legend>';
  114. if (in_array(
  115. $GLOBALS['cfg']['ActionLinksMode'],
  116. array('icons', 'both')
  117. )
  118. ) {
  119. $html_output .= PMA_Util::getImage('b_deltbl.png');
  120. }
  121. $html_output .= __('Remove database')
  122. . '</legend>';
  123. $html_output .= '<ul>';
  124. $html_output .= PMA_getDeleteDataOrTablelink(
  125. $this_url_params,
  126. 'DROP_DATABASE',
  127. __('Drop the database (DROP)'),
  128. 'drop_db_anchor'
  129. );
  130. $html_output .= '</ul></fieldset>'
  131. . '</div>';
  132. return $html_output;
  133. }
  134. /**
  135. * Get HTML snippet for copy database
  136. *
  137. * @param string $db database name
  138. *
  139. * @return string $html_output
  140. */
  141. function PMA_getHtmlForCopyDatabase($db)
  142. {
  143. $drop_clause = 'DROP TABLE / DROP VIEW';
  144. $choices = array(
  145. 'structure' => __('Structure only'),
  146. 'data' => __('Structure and data'),
  147. 'dataonly' => __('Data only')
  148. );
  149. if (isset($_COOKIE)
  150. && isset($_COOKIE['pma_switch_to_new'])
  151. && $_COOKIE['pma_switch_to_new'] == 'true'
  152. ) {
  153. $pma_switch_to_new = 'true';
  154. }
  155. $html_output = '<div class="operations_half_width clearfloat">';
  156. $html_output .= '<form id="copy_db_form" '
  157. . 'class="ajax" '
  158. . 'method="post" action="db_operations.php"'
  159. . 'onsubmit="return emptyFormElements(this, \'newname\')">';
  160. if (isset($_REQUEST['db_collation'])) {
  161. $html_output .= '<input type="hidden" name="db_collation" '
  162. . 'value="' . $_REQUEST['db_collation'] .'" />' . "\n";
  163. }
  164. $html_output .= '<input type="hidden" name="db_copy" value="true" />' . "\n"
  165. . PMA_generate_common_hidden_inputs($db);
  166. $html_output .= '<fieldset>'
  167. . '<legend>';
  168. if (in_array(
  169. $GLOBALS['cfg']['ActionLinksMode'],
  170. array('icons', 'both')
  171. )
  172. ) {
  173. $html_output .= PMA_Util::getImage('b_edit.png');
  174. }
  175. $html_output .= __('Copy database to') . ':'
  176. . '</legend>'
  177. . '<input type="text" name="newname" size="30" '
  178. . 'class="textfield" value="" /><br />'
  179. . PMA_Util::getRadioFields(
  180. 'what', $choices, 'data', true
  181. );
  182. $html_output .= '<input type="checkbox" name="create_database_before_copying" '
  183. . 'value="1" id="checkbox_create_database_before_copying"'
  184. . 'checked="checked" />';
  185. $html_output .= '<label for="checkbox_create_database_before_copying">'
  186. . __('CREATE DATABASE before copying') . '</label><br />';
  187. $html_output .= '<input type="checkbox" name="drop_if_exists" value="true"'
  188. . 'id="checkbox_drop" />';
  189. $html_output .= '<label for="checkbox_drop">'
  190. . sprintf(__('Add %s'), $drop_clause)
  191. . '</label><br />';
  192. $html_output .= '<input type="checkbox" name="sql_auto_increment" value="1" '
  193. . 'checked="checked" id="checkbox_auto_increment" />';
  194. $html_output .= '<label for="checkbox_auto_increment">'
  195. . __('Add AUTO_INCREMENT value') . '</label><br />';
  196. $html_output .= '<input type="checkbox" name="add_constraints" value="1"'
  197. . 'id="checkbox_constraints" />';
  198. $html_output .= '<label for="checkbox_constraints">'
  199. . __('Add constraints') . '</label><br />';
  200. $html_output .= '<input type="checkbox" name="switch_to_new" value="true"'
  201. . 'id="checkbox_switch"'
  202. . ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true')
  203. ? ' checked="checked"'
  204. : '')
  205. . '/>';
  206. $html_output .= '<label for="checkbox_switch">'
  207. . __('Switch to copied database') . '</label>'
  208. . '</fieldset>';
  209. $html_output .= '<fieldset class="tblFooters">'
  210. . '<input type="submit" name="submit_copy" value="' . __('Go') . '" />'
  211. . '</fieldset>'
  212. . '</form>'
  213. . '</div>';
  214. return $html_output;
  215. }
  216. /**
  217. * Get HTML snippet for change database charset
  218. *
  219. * @param string $db database name
  220. * @param string $table tabel name
  221. *
  222. * @return string $html_output
  223. */
  224. function PMA_getHtmlForChangeDatabaseCharset($db, $table)
  225. {
  226. $html_output = '<div class="operations_half_width">'
  227. . '<form id="change_db_charset_form" ';
  228. $html_output .= 'class="ajax" ';
  229. $html_output .= 'method="post" action="db_operations.php">';
  230. $html_output .= PMA_generate_common_hidden_inputs($db, $table);
  231. $html_output .= '<fieldset>' . "\n"
  232. . ' <legend>';
  233. if (in_array(
  234. $GLOBALS['cfg']['ActionLinksMode'],
  235. array('icons', 'both')
  236. )
  237. ) {
  238. $html_output .= PMA_Util::getImage('s_asci.png');
  239. }
  240. $html_output .= '<label for="select_db_collation">' . __('Collation')
  241. . ':</label>' . "\n"
  242. . '</legend>' . "\n"
  243. . PMA_generateCharsetDropdownBox(
  244. PMA_CSDROPDOWN_COLLATION,
  245. 'db_collation',
  246. 'select_db_collation',
  247. isset($_REQUEST['db_collation']) ? $_REQUEST['db_collation'] : '',
  248. false,
  249. 3
  250. )
  251. . '</fieldset>'
  252. . '<fieldset class="tblFooters">'
  253. . '<input type="submit" name="submitcollation"'
  254. . ' value="' . __('Go') . '" />' . "\n"
  255. . '</fieldset>' . "\n"
  256. . '</form></div>' . "\n";
  257. return $html_output;
  258. }
  259. /**
  260. * Get HTML snippet for export relational schema view
  261. *
  262. * @param string $url_query
  263. *
  264. * @return string $html_output
  265. */
  266. function PMA_getHtmlForExportRelationalSchemaView($url_query)
  267. {
  268. $html_output = '<div class="operations_full_width">'
  269. . '<fieldset><a href="schema_edit.php?' . $url_query . '">';
  270. if (in_array(
  271. $GLOBALS['cfg']['ActionLinksMode'],
  272. array('icons', 'both')
  273. )
  274. ) {
  275. $html_output .= PMA_Util::getImage(
  276. 'b_edit.png'
  277. );
  278. }
  279. $html_output .= __('Edit or export relational schema')
  280. . '</a></fieldset>'
  281. . '</div>';
  282. return $html_output;
  283. }
  284. /**
  285. * Run the Procedure definitions and function definitions
  286. *
  287. * to avoid selecting alternatively the current and new db
  288. * we would need to modify the CREATE definitions to qualify
  289. * the db name
  290. *
  291. * @param string $db database name
  292. *
  293. * @return void
  294. */
  295. function PMA_runProcedureAndFunctionDefinitions($db)
  296. {
  297. $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
  298. if ($procedure_names) {
  299. foreach ($procedure_names as $procedure_name) {
  300. PMA_DBI_select_db($db);
  301. $tmp_query = PMA_DBI_get_definition(
  302. $db, 'PROCEDURE', $procedure_name
  303. );
  304. // collect for later display
  305. $GLOBALS['sql_query'] .= "\n" . $tmp_query;
  306. PMA_DBI_select_db($_REQUEST['newname']);
  307. PMA_DBI_query($tmp_query);
  308. }
  309. }
  310. $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
  311. if ($function_names) {
  312. foreach ($function_names as $function_name) {
  313. PMA_DBI_select_db($db);
  314. $tmp_query = PMA_DBI_get_definition($db, 'FUNCTION', $function_name);
  315. // collect for later display
  316. $GLOBALS['sql_query'] .= "\n" . $tmp_query;
  317. PMA_DBI_select_db($_REQUEST['newname']);
  318. PMA_DBI_query($tmp_query);
  319. }
  320. }
  321. }
  322. /**
  323. * Get sql query and create database before copy
  324. *
  325. * @return string $sql_query
  326. */
  327. function PMA_getSqlQueryAndCreateDbBeforeCopy()
  328. {
  329. // lower_case_table_names=1 `DB` becomes `db`
  330. if (! PMA_DRIZZLE) {
  331. $lower_case_table_names = PMA_DBI_fetch_value(
  332. 'SHOW VARIABLES LIKE "lower_case_table_names"', 0, 1
  333. );
  334. if ($lower_case_table_names === '1') {
  335. $_REQUEST['newname'] = PMA_strtolower($_REQUEST['newname']);
  336. }
  337. }
  338. $local_query = 'CREATE DATABASE IF NOT EXISTS '
  339. . PMA_Util::backquote($_REQUEST['newname']);
  340. if (isset($_REQUEST['db_collation'])) {
  341. $local_query .= ' DEFAULT'
  342. . PMA_generateCharsetQueryPart($_REQUEST['db_collation']);
  343. }
  344. $local_query .= ';';
  345. $sql_query = $local_query;
  346. // save the original db name because Tracker.class.php which
  347. // may be called under PMA_DBI_query() changes $GLOBALS['db']
  348. // for some statements, one of which being CREATE DATABASE
  349. $original_db = $GLOBALS['db'];
  350. PMA_DBI_query($local_query);
  351. $GLOBALS['db'] = $original_db;
  352. // rebuild the database list because PMA_Table::moveCopy
  353. // checks in this list if the target db exists
  354. $GLOBALS['pma']->databases->build();
  355. return $sql_query;
  356. }
  357. /**
  358. * remove all foreign key constraints and return
  359. * sql constraints query for full database
  360. *
  361. * @param array $tables_full array of all tables in given db or dbs
  362. * @param object $export_sql_plugin export plugin instance
  363. * @param boolean $move whether databse name is empty or not
  364. * @param string $db database name
  365. *
  366. * @return string sql constraints query for full databases
  367. */
  368. function PMA_getSqlConstraintsQueryForFullDb(
  369. $tables_full, $export_sql_plugin, $move, $db
  370. ) {
  371. $sql_constraints_query_full_db = array();
  372. foreach ($tables_full as $each_table => $tmp) {
  373. $sql_constraints = '';
  374. $sql_drop_foreign_keys = '';
  375. $sql_structure = $export_sql_plugin->getTableDef(
  376. $db, $each_table, "\n", '', false, false
  377. );
  378. if ($move && ! empty($sql_drop_foreign_keys)) {
  379. PMA_DBI_query($sql_drop_foreign_keys);
  380. }
  381. // keep the constraint we just dropped
  382. if (! empty($sql_constraints)) {
  383. $sql_constraints_query_full_db[] = $sql_constraints;
  384. }
  385. }
  386. return $sql_constraints_query_full_db;
  387. }
  388. /**
  389. * Get views as an array and create SQL view stand-in
  390. *
  391. * @param array $tables_full array of all tables in given db or dbs
  392. * @param object $export_sql_plugin export plugin instance
  393. * @param strin $db database name
  394. *
  395. * @return array $views
  396. */
  397. function PMA_getViewsAndCreateSqlViewStandIn(
  398. $tables_full, $export_sql_plugin, $db
  399. ) {
  400. $views = array();
  401. foreach ($tables_full as $each_table => $tmp) {
  402. // to be able to rename a db containing views,
  403. // first all the views are collected and a stand-in is created
  404. // the real views are created after the tables
  405. if (PMA_Table::isView($db, $each_table)) {
  406. $views[] = $each_table;
  407. // Create stand-in definition to resolve view dependencies
  408. $sql_view_standin = $export_sql_plugin->getTableDefStandIn(
  409. $db, $each_table, "\n"
  410. );
  411. PMA_DBI_select_db($_REQUEST['newname']);
  412. PMA_DBI_query($sql_view_standin);
  413. $GLOBALS['sql_query'] .= "\n" . $sql_view_standin;
  414. }
  415. }
  416. return $views;
  417. }
  418. /**
  419. * Get sql query for copy/rename table and boolean for whether copy/rename or not
  420. *
  421. * @param array $tables_full array of all tables in given db or dbs
  422. * @param string $sql_query sql query for all operations
  423. * @param boolean $move whether databse name is empty or not
  424. * @param string $db database name
  425. *
  426. * @return array ($sql_query, $error)
  427. */
  428. function PMA_getSqlQueryForCopyTable($tables_full, $sql_query, $move, $db)
  429. {
  430. $error = false;
  431. foreach ($tables_full as $each_table => $tmp) {
  432. // skip the views; we have creted stand-in definitions
  433. if (PMA_Table::isView($db, $each_table)) {
  434. continue;
  435. }
  436. $back = $sql_query;
  437. $sql_query = '';
  438. // value of $what for this table only
  439. $this_what = $_REQUEST['what'];
  440. // do not copy the data from a Merge table
  441. // note: on the calling FORM, 'data' means 'structure and data'
  442. if (PMA_Table::isMerge($db, $each_table)) {
  443. if ($this_what == 'data') {
  444. $this_what = 'structure';
  445. }
  446. if ($this_what == 'dataonly') {
  447. $this_what = 'nocopy';
  448. }
  449. }
  450. if ($this_what != 'nocopy') {
  451. // keep the triggers from the original db+table
  452. // (third param is empty because delimiters are only intended
  453. // for importing via the mysql client or our Import feature)
  454. $triggers = PMA_DBI_get_triggers($db, $each_table, '');
  455. if (! PMA_Table::moveCopy(
  456. $db, $each_table, $_REQUEST['newname'], $each_table,
  457. (isset($this_what) ? $this_what : 'data'),
  458. $move, 'db_copy'
  459. )) {
  460. $error = true;
  461. // $sql_query is filled by PMA_Table::moveCopy()
  462. $sql_query = $back . $sql_query;
  463. break;
  464. }
  465. // apply the triggers to the destination db+table
  466. if ($triggers) {
  467. PMA_DBI_select_db($_REQUEST['newname']);
  468. foreach ($triggers as $trigger) {
  469. PMA_DBI_query($trigger['create']);
  470. $GLOBALS['sql_query'] .= "\n" . $trigger['create'] . ';';
  471. }
  472. }
  473. // this does not apply to a rename operation
  474. if (isset($_REQUEST['add_constraints'])
  475. && ! empty($GLOBALS['sql_constraints_query'])
  476. ) {
  477. $GLOBALS['sql_constraints_query_full_db'][]
  478. = $GLOBALS['sql_constraints_query'];
  479. unset($GLOBALS['sql_constraints_query']);
  480. }
  481. }
  482. // $sql_query is filled by PMA_Table::moveCopy()
  483. $sql_query = $back . $sql_query;
  484. }
  485. return array($sql_query, $error);
  486. }
  487. /**
  488. * Run the EVENT definition for selected database
  489. *
  490. * to avoid selecting alternatively the current and new db
  491. * we would need to modify the CREATE definitions to qualify
  492. * the db name
  493. *
  494. * @param string $db database name
  495. *
  496. * @return void
  497. */
  498. function PMA_runEventDefinitionsForDb($db)
  499. {
  500. $event_names = PMA_DBI_fetch_result(
  501. 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \''
  502. . PMA_Util::sqlAddSlashes($db, true) . '\';'
  503. );
  504. if ($event_names) {
  505. foreach ($event_names as $event_name) {
  506. PMA_DBI_select_db($db);
  507. $tmp_query = PMA_DBI_get_definition($db, 'EVENT', $event_name);
  508. // collect for later display
  509. $GLOBALS['sql_query'] .= "\n" . $tmp_query;
  510. PMA_DBI_select_db($_REQUEST['newname']);
  511. PMA_DBI_query($tmp_query);
  512. }
  513. }
  514. }
  515. /**
  516. * Handle the views, return the boolean value whether table rename/copy or not
  517. *
  518. * @param array $views views as an array
  519. * @param boolean $move whether databse name is empty or not
  520. * @param string $db database name
  521. *
  522. * @return boolean $_error whether table rename/copy or not
  523. */
  524. function PMA_handleTheViews($views, $move, $db)
  525. {
  526. $_error = false;
  527. // temporarily force to add DROP IF EXIST to CREATE VIEW query,
  528. // to remove stand-in VIEW that was created earlier
  529. // ( $_REQUEST['drop_if_exists'] is used in moveCopy() )
  530. if (isset($_REQUEST['drop_if_exists'])) {
  531. $temp_drop_if_exists = $_REQUEST['drop_if_exists'];
  532. }
  533. $_REQUEST['drop_if_exists'] = 'true';
  534. foreach ($views as $view) {
  535. $copying_succeeded = PMA_Table::moveCopy(
  536. $db, $view, $_REQUEST['newname'], $view, 'structure', $move, 'db_copy'
  537. );
  538. if (! $copying_succeeded) {
  539. $_error = true;
  540. break;
  541. }
  542. }
  543. unset($_REQUEST['drop_if_exists']);
  544. if (isset($temp_drop_if_exists)) {
  545. // restore previous value
  546. $_REQUEST['drop_if_exists'] = $temp_drop_if_exists;
  547. }
  548. return $_error;
  549. }
  550. /**
  551. * Create all accumulated constraaints
  552. *
  553. * @return void
  554. */
  555. function PMA_createAllAccumulatedConstraints()
  556. {
  557. PMA_DBI_select_db($_REQUEST['newname']);
  558. foreach ($GLOBALS['sql_constraints_query_full_db'] as $one_query) {
  559. PMA_DBI_query($one_query);
  560. // and prepare to display them
  561. $GLOBALS['sql_query'] .= "\n" . $one_query;
  562. }
  563. unset($GLOBALS['sql_constraints_query_full_db']);
  564. }
  565. /**
  566. * Duplicate the bookmarks for the db (done once for each db)
  567. *
  568. * @param boolean $_error whether table rename/copy or not
  569. * @param string $db database name
  570. *
  571. * @return void
  572. */
  573. function PMA_duplicateBookmarks($_error, $db)
  574. {
  575. if (! $_error && $db != $_REQUEST['newname']) {
  576. $get_fields = array('user', 'label', 'query');
  577. $where_fields = array('dbase' => $db);
  578. $new_fields = array('dbase' => $_REQUEST['newname']);
  579. PMA_Table::duplicateInfo(
  580. 'bookmarkwork', 'bookmark', $get_fields,
  581. $where_fields, $new_fields
  582. );
  583. }
  584. }
  585. /**
  586. * Get the HTML snippet for order the table
  587. *
  588. * @param array $columns columns array
  589. *
  590. * @return string $html_out
  591. */
  592. function PMA_getHtmlForOrderTheTable($columns)
  593. {
  594. $html_output = '<div class="operations_half_width">';
  595. $html_output .= '<form method="post" id="alterTableOrderby" '
  596. . 'action="tbl_operations.php">';
  597. $html_output .= PMA_generate_common_hidden_inputs(
  598. $GLOBALS['db'], $GLOBALS['table']
  599. );
  600. $html_output .= '<fieldset id="fieldset_table_order">'
  601. . '<legend>' . __('Alter table order by') . '</legend>'
  602. . '<select name="order_field">';
  603. foreach ($columns as $fieldname) {
  604. $html_output .= '<option '
  605. . 'value="' . htmlspecialchars($fieldname['Field']) . '">'
  606. . htmlspecialchars($fieldname['Field']) . '</option>' . "\n";
  607. }
  608. $html_output .= '</select> ' . __('(singly)') . ' '
  609. . '<select name="order_order">'
  610. . '<option value="asc">' . __('Ascending') . '</option>'
  611. . '<option value="desc">' . __('Descending') . '</option>'
  612. . '</select>'
  613. . '</fieldset>'
  614. . '<fieldset class="tblFooters">'
  615. . '<input type="hidden" name="submitorderby" value="1" />'
  616. . '<input type="submit" value="' . __('Go') . '" />'
  617. . '</fieldset>'
  618. . '</form>'
  619. . '</div>';
  620. return $html_output;
  621. }
  622. /**
  623. * Get the HTML snippet for move table
  624. *
  625. * @return string $html_output
  626. */
  627. function PMA_getHtmlForMoveTable()
  628. {
  629. $html_output = '<div class="operations_half_width">';
  630. $html_output .= '<form method="post" action="tbl_operations.php"'
  631. . ' id="moveTableForm" class="ajax"'
  632. . ' onsubmit="return emptyFormElements(this, \'new_name\')">'
  633. . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
  634. $html_output .= '<input type="hidden" name="reload" value="1" />'
  635. . '<input type="hidden" name="what" value="data" />'
  636. . '<fieldset id="fieldset_table_rename">';
  637. $html_output .= '<legend>' . __('Move table to (database<b>.</b>table):')
  638. . '</legend>';
  639. if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) {
  640. $html_output .= '<input type="text" maxlength="100" size="30" '
  641. . 'name="target_db" value="' . htmlspecialchars($GLOBALS['db'])
  642. . '"/>';
  643. } else {
  644. $html_output .= '<select name="target_db">'
  645. . $GLOBALS['pma']->databases->getHtmlOptions(true, false)
  646. . '</select>';
  647. }
  648. $html_output .= '&nbsp;<strong>.</strong>&nbsp;';
  649. $html_output .= '<input type="text" size="20" name="new_name"'
  650. . ' onfocus="this.select()"'
  651. . 'value="' . htmlspecialchars($GLOBALS['table']) . '" /><br />';
  652. // starting with MySQL 5.0.24, SHOW CREATE TABLE includes the AUTO_INCREMENT
  653. // next value but users can decide if they want it or not for the operation
  654. $html_output .= '<input type="checkbox" name="sql_auto_increment" '
  655. . 'value="1" id="checkbox_auto_increment_mv" checked="checked" />'
  656. . '<label for="checkbox_auto_increment_mv">'
  657. . __('Add AUTO_INCREMENT value')
  658. . '</label><br />'
  659. . '</fieldset>';
  660. $html_output .= '<fieldset class="tblFooters">'
  661. . '<input type="submit" name="submit_move" value="' . __('Go') . '" />'
  662. . '</fieldset>'
  663. . '</form>'
  664. . '</div>';
  665. return $html_output;
  666. }
  667. /**
  668. * Get the HTML div for Table option
  669. *
  670. * @param string $comment Comment
  671. * @param array $tbl_collation table collation
  672. * @param string $tbl_storage_engine table storage engine
  673. * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
  674. * @param boolean $is_isam whether ISAM or not
  675. * @param array $pack_keys pack keys
  676. * @param string $auto_increment value of auto increment
  677. * @param string $delay_key_write delay key write
  678. * @param string $transactional value of transactional
  679. * @param string $page_checksum value of page checksum
  680. * @param boolean $is_innodb whether INNODB or not
  681. * @param boolean $is_pbxt whether PBXT or not
  682. * @param boolean $is_aria whether ARIA or not
  683. * @param string $checksum the checksum
  684. *
  685. * @return string $html_output
  686. */
  687. function PMA_getTableOptionDiv($comment, $tbl_collation, $tbl_storage_engine,
  688. $is_myisam_or_aria, $is_isam, $pack_keys, $auto_increment, $delay_key_write,
  689. $transactional, $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum
  690. ) {
  691. $html_output = '<div class="operations_half_width clearfloat">';
  692. $html_output .= '<form method="post" action="tbl_operations.php"';
  693. $html_output .= ' id="tableOptionsForm" class="ajax">';
  694. $html_output .= PMA_generate_common_hidden_inputs(
  695. $GLOBALS['db'], $GLOBALS['table']
  696. );
  697. $html_output .= '<input type="hidden" name="reload" value="1" />';
  698. $html_output .= PMA_getTableOptionFieldset(
  699. $comment, $tbl_collation,
  700. $tbl_storage_engine, $is_myisam_or_aria, $is_isam, $pack_keys,
  701. $delay_key_write, $auto_increment, $transactional, $page_checksum,
  702. $is_innodb, $is_pbxt, $is_aria, $checksum
  703. );
  704. $html_output .= '<fieldset class="tblFooters">'
  705. . '<input type="hidden" name="submitoptions" value="1" />'
  706. . '<input type="submit" value="' . __('Go') . '" />'
  707. . '</fieldset>'
  708. . '</form>'
  709. . '</div>';
  710. return $html_output;
  711. }
  712. /**
  713. * Get HTML fieldset for Table option, it contains HTML table for options
  714. *
  715. * @param string $comment Comment
  716. * @param array $tbl_collation table collation
  717. * @param string $tbl_storage_engine table storage engine
  718. * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
  719. * @param boolean $is_isam whether ISAM or not
  720. * @param array $pack_keys pack keys
  721. * @param string $delay_key_write delay key write
  722. * @param string $auto_increment value of auto increment
  723. * @param string $transactional value of transactional
  724. * @param string $page_checksum value of page checksum
  725. * @param boolean $is_innodb whether INNODB or not
  726. * @param boolean $is_pbxt whether PBXT or not
  727. * @param boolean $is_aria whether ARIA or not
  728. * @param string $checksum the checksum
  729. *
  730. * @return string $html_output
  731. */
  732. function PMA_getTableOptionFieldset($comment, $tbl_collation,
  733. $tbl_storage_engine, $is_myisam_or_aria, $is_isam, $pack_keys,
  734. $delay_key_write, $auto_increment, $transactional,
  735. $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum
  736. ) {
  737. $html_output = '<fieldset>'
  738. . '<legend>' . __('Table options') . '</legend>';
  739. $html_output .= '<table>';
  740. //Change table name
  741. $html_output .= '<tr><td>' . __('Rename table to') . '</td>'
  742. . '<td>'
  743. . '<input type="text" size="20" name="new_name" onfocus="this.select()"'
  744. . 'value="' . htmlspecialchars($GLOBALS['table']) . '" />'
  745. . '</td>'
  746. . '</tr>';
  747. //Table comments
  748. $html_output .= '<tr><td>' . __('Table comments') . '</td>'
  749. . '<td><input type="text" name="comment" maxlength="60" size="30"'
  750. . 'value="' . htmlspecialchars($comment) . '" onfocus="this.select()" />'
  751. . '<input type="hidden" name="prev_comment" value="'
  752. . htmlspecialchars($comment) . '" />'
  753. . '</td>'
  754. . '</tr>';
  755. //Storage engine
  756. $html_output .= '<tr><td>' . __('Storage Engine')
  757. . PMA_Util::showMySQLDocu(
  758. 'Storage_engines', 'Storage_engines'
  759. )
  760. . '</td>'
  761. . '<td>'
  762. . PMA_StorageEngine::getHtmlSelect(
  763. 'new_tbl_storage_engine', null, $tbl_storage_engine
  764. )
  765. . '</td>'
  766. . '</tr>';
  767. //Table character set
  768. $html_output .= '<tr><td>' . __('Collation') . '</td>'
  769. . '<td>'
  770. . PMA_generateCharsetDropdownBox(
  771. PMA_CSDROPDOWN_COLLATION,
  772. 'tbl_collation', null, $tbl_collation, false, 3
  773. )
  774. . '</td>'
  775. . '</tr>';
  776. if ($is_myisam_or_aria || $is_isam) {
  777. $html_output .= '<tr>'
  778. . '<td><label for="new_pack_keys">PACK_KEYS</label></td>'
  779. . '<td><select name="new_pack_keys" id="new_pack_keys">';
  780. $html_output .= '<option value="DEFAULT"';
  781. if ($pack_keys == 'DEFAULT') {
  782. $html_output .= 'selected="selected"';
  783. }
  784. $html_output .= '>DEFAULT</option>
  785. <option value="0"';
  786. if ($pack_keys == '0') {
  787. $html_output .= 'selected="selected"';
  788. }
  789. $html_output .= '>0</option>
  790. <option value="1" ';
  791. if ($pack_keys == '1') {
  792. $html_output .= 'selected="selected"';
  793. }
  794. $html_output .= '>1</option>'
  795. . '</select>'
  796. . '</td>'
  797. . '</tr>';
  798. } // end if (MYISAM|ISAM)
  799. if ($is_myisam_or_aria) {
  800. $html_output .= PMA_getHtmlForTableRow(
  801. 'new_checksum',
  802. 'CHECKSUM',
  803. $checksum
  804. );
  805. $html_output .= PMA_getHtmlForTableRow(
  806. 'new_delay_key_write',
  807. 'DELAY_KEY_WRITE',
  808. $delay_key_write
  809. );
  810. } // end if (MYISAM)
  811. if ($is_aria) {
  812. $html_output .= PMA_getHtmlForTableRow(
  813. 'new_transactional',
  814. 'TRANSACTIONAL',
  815. $transactional
  816. );
  817. $html_output .= PMA_getHtmlForTableRow(
  818. 'new_page_checksum',
  819. 'PAGE_CHECKSUM',
  820. $page_checksum
  821. );
  822. } // end if (ARIA)
  823. if (strlen($auto_increment) > 0
  824. && ($is_myisam_or_aria || $is_innodb || $is_pbxt)
  825. ) {
  826. $html_output .= '<tr><td>'
  827. . '<label for="auto_increment_opt">AUTO_INCREMENT</label></td>'
  828. . '<td><input type="text" name="new_auto_increment" '
  829. . 'id="auto_increment_opt"'
  830. . 'value="' . $auto_increment . '" /></td>'
  831. . '</tr> ';
  832. } // end if (MYISAM|INNODB)
  833. $possible_row_formats = PMA_getPossibleRowFormat();
  834. // for MYISAM there is also COMPRESSED but it can be set only by the
  835. // myisampack utility, so don't offer here the choice because if we
  836. // try it inside an ALTER TABLE, MySQL (at least in 5.1.23-maria)
  837. // does not return a warning
  838. // (if the table was compressed, it can be seen on the Structure page)
  839. if (isset($possible_row_formats[$tbl_storage_engine])) {
  840. $current_row_format = strtoupper($GLOBALS['showtable']['Row_format']);
  841. $html_output .= '<tr><td>'
  842. . '<label for="new_row_format">ROW_FORMAT</label></td>'
  843. . '<td>';
  844. $html_output .= PMA_Util::getDropdown(
  845. 'new_row_format', $possible_row_formats[$tbl_storage_engine],
  846. $current_row_format, 'new_row_format'
  847. );
  848. $html_output .= '</td></tr>';
  849. }
  850. $html_output .= '</table>'
  851. . '</fieldset>';
  852. return $html_output;
  853. }
  854. /**
  855. * Get the common HTML table row (tr) for new_checksum, new_delay_key_write,
  856. * new_transactional and new_page_checksum
  857. *
  858. * @param string $attribute class, name and id attribute
  859. * @param string $label label value
  860. * @param string $val checksum, delay_key_write, transactional, page_checksum
  861. *
  862. * @return string $html_output
  863. */
  864. function PMA_getHtmlForTableRow($attribute, $label, $val)
  865. {
  866. return '<tr>'
  867. . '<td><label for="' . $attribute . '">' . $label . '</label></td>'
  868. . '<td><input type="checkbox" name="'. $attribute .'"'
  869. . ' id="' . $attribute .'"'
  870. . ' value="1"'
  871. . ((!empty($val) && $val == 1) ? ' checked="checked"' : '') . '/></td>'
  872. . '</tr>';
  873. }
  874. /**
  875. * Get array of possible row formats
  876. *
  877. * @return array $possible_row_formats
  878. */
  879. function PMA_getPossibleRowFormat()
  880. {
  881. // the outer array is for engines, the inner array contains the dropdown
  882. // option values as keys then the dropdown option labels
  883. $possible_row_formats = array(
  884. 'ARIA' => array(
  885. 'FIXED' => 'FIXED',
  886. 'DYNAMIC' => 'DYNAMIC',
  887. 'PAGE' => 'PAGE'
  888. ),
  889. 'MARIA' => array(
  890. 'FIXED' => 'FIXED',
  891. 'DYNAMIC' => 'DYNAMIC',
  892. 'PAGE' => 'PAGE'
  893. ),
  894. 'MYISAM' => array(
  895. 'FIXED' => 'FIXED',
  896. 'DYNAMIC' => 'DYNAMIC'
  897. ),
  898. 'PBXT' => array(
  899. 'FIXED' => 'FIXED',
  900. 'DYNAMIC' => 'DYNAMIC'
  901. ),
  902. 'INNODB' => array(
  903. 'COMPACT' => 'COMPACT',
  904. 'REDUNDANT' => 'REDUNDANT'
  905. )
  906. );
  907. $innodb_engine_plugin = PMA_StorageEngine::getEngine('innodb');
  908. $innodb_plugin_version = $innodb_engine_plugin->getInnodbPluginVersion();
  909. if (!empty($innodb_plugin_version)) {
  910. $innodb_file_format = $innodb_engine_plugin->getInnodbFileFormat();
  911. } else {
  912. $innodb_file_format = '';
  913. }
  914. if ('Barracuda' == $innodb_file_format
  915. && $innodb_engine_plugin->supportsFilePerTable()
  916. ) {
  917. $possible_row_formats['INNODB']['DYNAMIC'] = 'DYNAMIC';
  918. $possible_row_formats['INNODB']['COMPRESSED'] = 'COMPRESSED';
  919. }
  920. return $possible_row_formats;
  921. }
  922. /**
  923. * Get HTML div for copy table
  924. *
  925. * @return string $html_output
  926. */
  927. function PMA_getHtmlForCopytable()
  928. {
  929. $html_output = '<div class="operations_half_width">';
  930. $html_output .= '<form method="post" action="tbl_operations.php" '
  931. . 'name="copyTable" '
  932. . 'id="copyTable" '
  933. . ' class="ajax" '
  934. . 'onsubmit="return emptyFormElements(this, \'new_name\')">'
  935. . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
  936. . '<input type="hidden" name="reload" value="1" />';
  937. $html_output .= '<fieldset>';
  938. $html_output .= '<legend>'
  939. . __('Copy table to (database<b>.</b>table):') . '</legend>';
  940. if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) {
  941. $html_output .= '<input type="text" maxlength="100" '
  942. . 'size="30" name="target_db" '
  943. . 'value="'. htmlspecialchars($GLOBALS['db']) . '"/>';
  944. } else {
  945. $html_output .= '<select name="target_db">'
  946. . $GLOBALS['pma']->databases->getHtmlOptions(true, false)
  947. . '</select>';
  948. }
  949. $html_output .= '&nbsp;<strong>.</strong>&nbsp;';
  950. $html_output .= '<input type="text" size="20" name="new_name" '
  951. . 'onfocus="this.select()" '
  952. . 'value="'. htmlspecialchars($GLOBALS['table']) . '"/><br />';
  953. $choices = array(
  954. 'structure' => __('Structure only'),
  955. 'data' => __('Structure and data'),
  956. 'dataonly' => __('Data only'));
  957. $html_output .= PMA_Util::getRadioFields(
  958. 'what', $choices, 'data', true
  959. );
  960. $html_output .= '<input type="checkbox" name="drop_if_exists" '
  961. . 'value="true" id="checkbox_drop" />'
  962. . '<label for="checkbox_drop">'
  963. . sprintf(__('Add %s'), 'DROP TABLE') . '</label><br />'
  964. . '<input type="checkbox" name="sql_auto_increment" '
  965. . 'value="1" id="checkbox_auto_increment_cp" />'
  966. . '<label for="checkbox_auto_increment_cp">'
  967. . __('Add AUTO_INCREMENT value') . '</label><br />';
  968. // display "Add constraints" choice only if there are
  969. // foreign keys
  970. if (PMA_getForeigners($GLOBALS['db'], $GLOBALS['table'], '', 'foreign')) {
  971. $html_output .= '<input type="checkbox" name="add_constraints" '
  972. . 'value="1" id="checkbox_constraints" />';
  973. $html_output .= '<label for="checkbox_constraints">'
  974. .__('Add constraints') . '</label><br />';
  975. } // endif
  976. if (isset($_COOKIE['pma_switch_to_new'])
  977. && $_COOKIE['pma_switch_to_new'] == 'true'
  978. ) {
  979. $pma_switch_to_new = 'true';
  980. }
  981. $html_output .= '<input type="checkbox" name="switch_to_new" value="true"'
  982. . 'id="checkbox_switch"'
  983. . ((isset($pma_switch_to_new) && $pma_switch_to_new == 'true')
  984. ? ' checked="checked"'
  985. : '' . '/>');
  986. $html_output .= '<label for="checkbox_switch">'
  987. . __('Switch to copied table') . '</label>'
  988. . '</fieldset>';
  989. $html_output .= '<fieldset class="tblFooters">'
  990. . '<input type="submit" name="submit_copy" value="' .__('Go') . '" />'
  991. . '</fieldset>'
  992. . '</form>'
  993. . '</div>';
  994. return $html_output;
  995. }
  996. /**
  997. * Get HTML snippet for table maintence
  998. *
  999. * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
  1000. * @param boolean $is_innodb whether innodb or not
  1001. * @param boolean $is_berkeleydb whether berkeleydb or not
  1002. * @param array $url_params array of URL parameters
  1003. *
  1004. * @return string $html_output
  1005. */
  1006. function PMA_getHtmlForTableMaintenance(
  1007. $is_myisam_or_aria, $is_innodb, $is_berkeleydb, $url_params
  1008. ) {
  1009. $html_output = '<div class="operations_half_width">';
  1010. $html_output .= '<fieldset>'
  1011. . '<legend>' . __('Table maintenance') . '</legend>';
  1012. $html_output .= '<ul id="tbl_maintenance">';
  1013. // Note: BERKELEY (BDB) is no longer supported, starting with MySQL 5.1
  1014. $html_output .= PMA_getListofMaintainActionLink(
  1015. $is_myisam_or_aria, $is_innodb, $url_params, $is_berkeleydb
  1016. );
  1017. $html_output .= '</ul>'
  1018. . '</fieldset>'
  1019. . '</div>';
  1020. return $html_output;
  1021. }
  1022. /**
  1023. * Get HTML 'li' having a link of maintain action
  1024. *
  1025. * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
  1026. * @param boolean $is_innodb whether innodb or not
  1027. * @param array $url_params array of URL parameters
  1028. * @param boolean $is_berkeleydb whether berkeleydb or not
  1029. *
  1030. * @return string $html_output
  1031. */
  1032. function PMA_getListofMaintainActionLink($is_myisam_or_aria,
  1033. $is_innodb, $url_params, $is_berkeleydb
  1034. ) {
  1035. $html_output = '';
  1036. if ($is_myisam_or_aria || $is_innodb || $is_berkeleydb) {
  1037. if ($is_myisam_or_aria || $is_innodb) {
  1038. $params = array(
  1039. 'sql_query' => 'CHECK TABLE '
  1040. . PMA_Util::backquote($GLOBALS['table']),
  1041. 'table_maintenance' => 'Go',
  1042. );
  1043. $html_output .= PMA_getMaintainActionlink(
  1044. __('Check table'),
  1045. $params,
  1046. $url_params,
  1047. 'CHECK_TABLE'
  1048. );
  1049. }
  1050. if ($is_innodb) {
  1051. $params = array(
  1052. 'sql_query' => 'ALTER TABLE '
  1053. . PMA_Util::backquote($GLOBALS['table'])
  1054. . ' ENGINE = InnoDB;'
  1055. );
  1056. $html_output .= PMA_getMaintainActionlink(
  1057. __('Defragment table'),
  1058. $params,
  1059. $url_params,
  1060. 'InnoDB_File_Defragmenting',
  1061. 'Table_types'
  1062. );
  1063. }
  1064. if ($is_innodb || $is_myisam_or_aria || $is_berkeleydb) {
  1065. $params = array(
  1066. 'sql_query' => 'ANALYZE TABLE '
  1067. . PMA_Util::backquote($GLOBALS['table']),
  1068. 'table_maintenance' => 'Go',
  1069. );
  1070. $html_output .= PMA_getMaintainActionlink(
  1071. __('Analyze table'),
  1072. $params,
  1073. $url_params,
  1074. 'ANALYZE_TABLE'
  1075. );
  1076. }
  1077. if ($is_myisam_or_aria && !PMA_DRIZZLE) {
  1078. $params = array(
  1079. 'sql_query' => 'REPAIR TABLE '
  1080. . PMA_Util::backquote($GLOBALS['table']),
  1081. 'table_maintenance' => 'Go',
  1082. );
  1083. $html_output .= PMA_getMaintainActionlink(
  1084. __('Repair table'),
  1085. $params,
  1086. $url_params,
  1087. 'REPAIR_TABLE'
  1088. );
  1089. }
  1090. if (($is_myisam_or_aria || $is_innodb || $is_berkeleydb)
  1091. && !PMA_DRIZZLE
  1092. ) {
  1093. $params = array(
  1094. 'sql_query' => 'OPTIMIZE TABLE '
  1095. . PMA_Util::backquote($GLOBALS['table']),
  1096. 'table_maintenance' => 'Go',
  1097. );
  1098. $html_output .= PMA_getMaintainActionlink(
  1099. __('Optimize table'),
  1100. $params,
  1101. $url_params,
  1102. 'OPTIMIZE_TABLE'
  1103. );
  1104. }
  1105. } // end MYISAM or BERKELEYDB case
  1106. $params = array(
  1107. 'sql_query' => 'FLUSH TABLE '
  1108. . PMA_Util::backquote($GLOBALS['table']),
  1109. 'message_to_show' => sprintf(
  1110. __('Table %s has been flushed'),
  1111. htmlspecialchars($GLOBALS['table'])
  1112. ),
  1113. 'reload' => 1,
  1114. );
  1115. $html_output .= PMA_getMaintainActionlink(
  1116. __('Flush the table (FLUSH)'),
  1117. $params,
  1118. $url_params,
  1119. 'FLUSH'
  1120. );
  1121. return $html_output;
  1122. }
  1123. /**
  1124. * Get maintain action HTML link
  1125. *
  1126. * @param string $action
  1127. * @param array $params url parameters array
  1128. * @param array $url_params
  1129. * @param string $link contains name of page/anchor that is being linked
  1130. * @param string $chapter chapter of "HTML, one page per chapter" documentation
  1131. *
  1132. * @return string $html_output
  1133. */
  1134. function PMA_getMaintainActionlink($action, $params, $url_params, $link,
  1135. $chapter = 'MySQL_Database_Administration'
  1136. ) {
  1137. return '<li>'
  1138. . '<a class="maintain_action ajax" '
  1139. . 'href="sql.php'
  1140. . PMA_generate_common_url(array_merge($url_params, $params)) .'">'
  1141. . $action
  1142. . '</a>'
  1143. . PMA_Util::showMySQLDocu($chapter, $link)
  1144. . '</li>';
  1145. }
  1146. /**
  1147. * Get HTML for Delete data or table (truncate table, drop table)
  1148. *
  1149. * @param array $truncate_table_url_params url parameter array for truncate table
  1150. * @param array $drop_table_url_params url parameter array for drop table
  1151. *
  1152. * @return string $html_output
  1153. */
  1154. function PMA_getHtmlForDeleteDataOrTable(
  1155. $truncate_table_url_params,
  1156. $drop_table_url_params
  1157. ) {
  1158. $html_output = '<div class="operations_half_width">'
  1159. . '<fieldset class="caution">'
  1160. . '<legend>' . __('Delete data or table') . '</legend>';
  1161. $html_output .= '<ul>';
  1162. if (! empty($truncate_table_url_params)) {
  1163. $html_output .= PMA_getDeleteDataOrTablelink(
  1164. $truncate_table_url_params,
  1165. 'TRUNCATE_TABLE',
  1166. __('Empty the table (TRUNCATE)'),
  1167. 'truncate_tbl_anchor'
  1168. );
  1169. }
  1170. if (!empty ($drop_table_url_params)) {
  1171. $html_output .= PMA_getDeleteDataOrTablelink(
  1172. $drop_table_url_params,
  1173. 'DROP_TABLE',
  1174. __('Delete the table (DROP)'),
  1175. 'drop_tbl_anchor'
  1176. );
  1177. }
  1178. $html_output .= '</ul></fieldset></div>';
  1179. return $html_output;
  1180. }
  1181. /**
  1182. * Get the HTML link for Truncate table, Drop table and Drop db
  1183. *
  1184. * @param array $url_params url parameter array for delete data or table
  1185. * @param string $syntax TRUNCATE_TABLE or DROP_TABLE or DROP_DATABASE
  1186. * @param string $link link to be shown
  1187. * @param string $id id of the link
  1188. *
  1189. * @return String html output
  1190. */
  1191. function PMA_getDeleteDataOrTablelink($url_params, $syntax, $link, $id)
  1192. {
  1193. return '<li><a '
  1194. . 'href="sql.php' . PMA_generate_common_url($url_params) . '"'
  1195. . ' id="' . $id . '" class="ajax">'
  1196. . $link . '</a>'
  1197. . PMA_Util::showMySQLDocu(
  1198. 'SQL-Syntax', $syntax
  1199. )
  1200. . '</li>';
  1201. }
  1202. /**
  1203. * Get HTML snippet for partition maintenance
  1204. *
  1205. * @param array $partition_names array of partition names for a specific db/table
  1206. * @param array $url_params url parameters
  1207. *
  1208. * @return string $html_output
  1209. */
  1210. function PMA_getHtmlForPartitionMaintenance($partition_names, $url_params)
  1211. {
  1212. $choices = array(
  1213. 'ANALYZE' => __('Analyze'),
  1214. 'CHECK' => __('Check'),
  1215. 'OPTIMIZE' => __('Optimize'),
  1216. 'REBUILD' => __('Rebuild'),
  1217. 'REPAIR' => __('Repair')
  1218. );
  1219. $html_output = '<div class="operations_half_width">'
  1220. . '<form method="post" action="tbl_operations.php">'
  1221. . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table'])
  1222. . '<fieldset>'
  1223. . '<legend>' . __('Partition maintenance') . '</legend>';
  1224. $html_select = '<select name="partition_name">' . "\n";
  1225. foreach ($partition_names as $one_partition) {
  1226. $one_partition = htmlspecialchars($one_partition);
  1227. $html_select .= '<option value="' . $one_partition . '">'
  1228. . $one_partition . '</option>' . "\n";
  1229. }
  1230. $html_select .= '</select>' . "\n";
  1231. $html_output .= sprintf(__('Partition %s'), $html_select);
  1232. $html_output .= PMA_Util::getRadioFields(
  1233. 'partition_operation', $choices, '', false
  1234. );
  1235. $html_output .= PMA_Util::showMySQLDocu(
  1236. 'partitioning_maintenance',
  1237. 'partitioning_maintenance'
  1238. );
  1239. $this_url_params = array_merge(
  1240. $url_params,
  1241. array(
  1242. 'sql_query' => 'ALTER TABLE '
  1243. . PMA_Util::backquote($GLOBALS['table'])
  1244. . ' REMOVE PARTITIONING;'
  1245. )
  1246. );
  1247. $html_output .= '<br /><a href="sql.php'
  1248. . PMA_generate_common_url($this_url_params) . '">'
  1249. . __('Remove partitioning') . '</a>';
  1250. $html_output .= '</fieldset>'
  1251. . '<fieldset class="tblFooters">'
  1252. . '<input type="submit" name="submit_partition" '
  1253. . 'value="' . __('Go') . '" />'
  1254. . '</fieldset>'
  1255. . '</form>'
  1256. . '</div>';
  1257. return $html_output;
  1258. }
  1259. /**
  1260. * Get the HTML for Referential Integrity check
  1261. *
  1262. * @param array $foreign all Relations to foreign tables for a given table
  1263. * or optionally a given column in a table
  1264. * @param array $url_params array of url parameters
  1265. *
  1266. * @return string $html_output
  1267. */
  1268. function PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params)
  1269. {
  1270. $html_output = '<div class="operations_half_width">'
  1271. . '<fieldset>'
  1272. . '<legend>' . __('Check referential integrity:') . '</legend>';
  1273. $html_output .= '<ul>';
  1274. foreach ($foreign AS $master => $arr) {
  1275. $join_query = 'SELECT '
  1276. . PMA_Util::backquote($GLOBALS['table']) . '.*'
  1277. . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
  1278. . ' LEFT JOIN '
  1279. . PMA_Util::backquote($arr['foreign_db'])
  1280. . '.'
  1281. . PMA_Util::backquote($arr['foreign_table']);
  1282. if ($arr['foreign_table'] == $GLOBALS['table']) {
  1283. $foreign_table = $GLOBALS['table'] . '1';
  1284. $join_query .= ' AS ' . PMA_Util::backquote($foreign_table);
  1285. } else {
  1286. $foreign_table = $arr['foreign_table'];
  1287. }
  1288. $join_query .= ' ON '
  1289. . PMA_Util::backquote($GLOBALS['table']) . '.'
  1290. . PMA_Util::backquote($master)
  1291. . ' = '
  1292. . PMA_Util::backquote($arr['foreign_db'])
  1293. . '.'
  1294. . PMA_Util::backquote($foreign_table) . '.'
  1295. . PMA_Util::backquote($arr['foreign_field'])
  1296. . ' WHERE '
  1297. . PMA_Util::backquote($arr['foreign_db'])
  1298. . '.'
  1299. . PMA_Util::backquote($foreign_table) . '.'
  1300. . PMA_Util::backquote($arr['foreign_field'])
  1301. . ' IS NULL AND '
  1302. . PMA_Util::backquote($GLOBALS['table']) . '.'
  1303. . PMA_Util::backquote($master)
  1304. . ' IS NOT NULL';
  1305. $this_url_params = array_merge(
  1306. $url_params,
  1307. array('sql_query' => $join_query)
  1308. );
  1309. $html_output .= '<li>'
  1310. . '<a href="sql.php'
  1311. . PMA_generate_common_url($this_url_params)
  1312. . '">'
  1313. . $master . '&nbsp;->&nbsp;' . $arr['foreign_table'] . '.'
  1314. . $arr['foreign_field']
  1315. . '</a></li>' . "\n";
  1316. } // foreach $foreign
  1317. $html_output .= '</ul></fieldset></div>';
  1318. return $html_output;
  1319. }
  1320. function PMA_getQueryAndResultForReorderingTable()
  1321. {
  1322. $sql_query = 'ALTER TABLE '
  1323. . PMA_Util::backquote($GLOBALS['table'])
  1324. . ' ORDER BY '
  1325. . PMA_Util::backquote(urldecode($_REQUEST['order_field']));
  1326. if (isset($_REQUEST['order_order'])
  1327. && $_REQUEST['order_order'] === 'desc'
  1328. ) {
  1329. $sql_query .= ' DESC';
  1330. }
  1331. $sql_query .= ';';
  1332. $result = PMA_DBI_query($sql_query);
  1333. return array($sql_query, $result);
  1334. }
  1335. /**
  1336. * Get table alters array
  1337. *
  1338. * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not
  1339. * @param boolean $is_isam whether ISAM or not
  1340. * @param string $pack_keys pack keys
  1341. * @param string $checksum value of checksum
  1342. * @param boolean $is_aria whether ARIA or not
  1343. * @param string $page_checksum value of page checksum
  1344. * @param string $delay_key_write delay key write
  1345. * @param boolean $is_innodb whether INNODB or not
  1346. * @param boolean $is_pbxt whether PBXT or not
  1347. * @param string $row_format row format
  1348. * @param string $tbl_storage_engine table storage engine
  1349. * @param string $transactional value of transactional
  1350. * @param string $tbl_collation collation of the table
  1351. *
  1352. * @return array $table_alters
  1353. */
  1354. function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys,
  1355. $checksum, $is_aria, $page_checksum, $delay_key_write, $is_innodb,
  1356. $is_pbxt, $row_format, $new_tbl_storage_engine, $transactional, $tbl_collation
  1357. ) {
  1358. global $auto_increment;
  1359. $table_alters = array();
  1360. if (isset($_REQUEST['comment'])
  1361. && urldecode($_REQUEST['prev_comment']) !== $_REQUEST['comment']
  1362. ) {
  1363. $table_alters[] = 'COMMENT = \''
  1364. . PMA_Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
  1365. }
  1366. if (! empty($new_tbl_storage_engine)
  1367. && strtolower($new_tbl_storage_engine) !== strtolower($GLOBALS['tbl_storage_engine'])
  1368. ) {
  1369. $table_alters[] = 'ENGINE = ' . $new_tbl_storage_engine;
  1370. }
  1371. if (! empty($_REQUEST['tbl_collation'])
  1372. && $_REQUEST['tbl_collation'] !== $tbl_collation
  1373. ) {
  1374. $table_alters[] = 'DEFAULT '
  1375. . PMA_generateCharsetQueryPart($_REQUEST['tbl_collation']);
  1376. }
  1377. if (($is_myisam_or_aria || $is_isam)
  1378. && isset($_REQUEST['new_pack_keys'])
  1379. && $_REQUEST['new_pack_keys'] != (string)$pack_keys
  1380. ) {
  1381. $table_alters[] = 'pack_keys = ' . $_REQUEST['new_pack_keys'];
  1382. }
  1383. $_REQUEST['new_checksum'] = empty($_REQUEST['new_checksum']) ? '0' : '1';
  1384. if ($is_myisam_or_aria
  1385. && $_REQUEST['new_checksum'] !== $checksum
  1386. ) {
  1387. $table_alters[] = 'checksum = ' . $_REQUEST['new_checksum'];
  1388. }
  1389. $_REQUEST['new_transactional']
  1390. = empty($_REQUEST['new_transactional']) ? '0' : '1';
  1391. if ($is_aria
  1392. && $_REQUEST['new_transactional'] !== $transactional
  1393. ) {
  1394. $table_alters[] = 'TRANSACTIONAL = ' . $_REQUEST['new_transactional'];
  1395. }
  1396. $_REQUEST['new_page_checksum']
  1397. = empty($_REQUEST['new_page_checksum']) ? '0' : '1';
  1398. if ($is_aria
  1399. && $_REQUEST['new_page_checksum'] !== $page_checksum
  1400. ) {
  1401. $table_alters[] = 'PAGE_CHECKSUM = ' . $_REQUEST['new_page_checksum'];
  1402. }
  1403. $_REQUEST['new_delay_key_write']
  1404. = empty($_REQUEST['new_delay_key_write']) ? '0' : '1';
  1405. if ($is_myisam_or_aria
  1406. && $_REQUEST['new_delay_key_write'] !== $delay_key_write
  1407. ) {
  1408. $table_alters[] = 'delay_key_write = ' . $_REQUEST['new_delay_key_write'];
  1409. }
  1410. if (($is_myisam_or_aria || $is_innodb || $is_pbxt)
  1411. && ! empty($_REQUEST['new_auto_increment'])
  1412. && (! isset($auto_increment)
  1413. || $_REQUEST['new_auto_increment'] !== $auto_increment)
  1414. ) {
  1415. $table_alters[] = 'auto_increment = '
  1416. . PMA_Util::sqlAddSlashes($_REQUEST['new_auto_increment']);
  1417. }
  1418. if (($is_myisam_or_aria || $is_innodb || $is_pbxt)
  1419. && ! empty($_REQUEST['new_row_format'])
  1420. && (!strlen($row_format)
  1421. || strtolower($_REQUEST['new_row_format']) !== strtolower($row_format))
  1422. ) {
  1423. $table_alters[] = 'ROW_FORMAT = '
  1424. . PMA_Util::sqlAddSlashes($_REQUEST['new_row_format']);
  1425. }
  1426. return $table_alters;
  1427. }
  1428. /**
  1429. * set initial value of the set of variables, based on the current table engine
  1430. *
  1431. * @param string $tbl_storage_engine table storage engine
  1432. *
  1433. * @return array ($is_myisam_or_aria, $is_innodb, $is_isam,
  1434. * $is_berkeleydb, $is_aria, $is_pbxt)
  1435. */
  1436. function PMA_setGlobalVariablesForEngine($tbl_storage_engine)
  1437. {
  1438. $is_myisam_or_aria = $is_isam = $is_innodb = $is_berkeleydb
  1439. = $is_aria = $is_pbxt = false;
  1440. $upper_tbl_storage_engine = strtoupper($tbl_storage_engine);
  1441. //Options that apply to MYISAM usually apply to ARIA
  1442. $is_myisam_or_aria = ($upper_tbl_storage_engine == 'MYISAM'
  1443. || $upper_tbl_storage_engine == 'ARIA'
  1444. || $upper_tbl_storage_engine == 'MARIA'
  1445. );
  1446. $is_aria = ($upper_tbl_storage_engine == 'ARIA');
  1447. $is_isam = ($upper_tbl_storage_engine == 'ISAM');
  1448. $is_innodb = ($upper_tbl_storage_engine == 'INNODB');
  1449. $is_berkeleydb = ($upper_tbl_storage_engine == 'BERKELEYDB');
  1450. $is_pbxt = ($upper_tbl_storage_engine == 'PBXT');
  1451. return array(
  1452. $is_myisam_or_aria, $is_innodb, $is_isam,
  1453. $is_berkeleydb, $is_aria, $is_pbxt
  1454. );
  1455. }
  1456. /**
  1457. * Get warning messages array
  1458. *
  1459. * @return array $warning_messages
  1460. */
  1461. function PMA_getWarningMessagesArray()
  1462. {
  1463. $warning_messages = array();
  1464. foreach (PMA_DBI_get_warnings() as $warning) {
  1465. // In MariaDB 5.1.44, when altering a table from Maria to MyISAM
  1466. // and if TRANSACTIONAL was set, the system reports an error;
  1467. // I discussed with a Maria developer and he agrees that this
  1468. // should not be reported with a Level of Error, so here
  1469. // I just ignore it. But there are other 1478 messages
  1470. // that it's better to show.
  1471. if (! ($_REQUEST['new_tbl_storage_engine'] == 'MyISAM'
  1472. && $warning['Code'] == '1478'
  1473. && $warning['Level'] == 'Error')
  1474. ) {
  1475. $warning_messages[] = $warning['Level'] . ': #' . $warning['Code']
  1476. . ' ' . $warning['Message'];
  1477. }
  1478. }
  1479. return $warning_messages;
  1480. }
  1481. /**
  1482. * Get SQL query and result after ran this SQL query for a partition operation
  1483. * has been requested by the user
  1484. *
  1485. * @return array $sql_query, $result
  1486. */
  1487. function PMA_getQueryAndResultForPartition()
  1488. {
  1489. $sql_query = 'ALTER TABLE '
  1490. . PMA_Util::backquote($GLOBALS['table']) . ' '
  1491. . $_REQUEST['partition_operation']
  1492. . ' PARTITION '
  1493. . $_REQUEST['partition_name'] . ';';
  1494. $result = PMA_DBI_query($sql_query);
  1495. return array($sql_query, $result);
  1496. }
  1497. ?>