tbl_operations.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Various table operations
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. *
  10. */
  11. require_once 'libraries/common.inc.php';
  12. /**
  13. * functions implementation for this script
  14. */
  15. require_once 'libraries/operations.lib.php';
  16. $pma_table = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
  17. $response = PMA_Response::getInstance();
  18. /**
  19. * Runs common work
  20. */
  21. require 'libraries/tbl_common.inc.php';
  22. $url_query .= '&amp;goto=tbl_operations.php&amp;back=tbl_operations.php';
  23. $url_params['goto'] = $url_params['back'] = 'tbl_operations.php';
  24. /**
  25. * Gets relation settings
  26. */
  27. $cfgRelation = PMA_getRelationsParam();
  28. /**
  29. * Gets available MySQL charsets and storage engines
  30. */
  31. require_once 'libraries/mysql_charsets.inc.php';
  32. require_once 'libraries/StorageEngine.class.php';
  33. /**
  34. * Class for partition management
  35. */
  36. require_once 'libraries/Partition.class.php';
  37. // reselect current db (needed in some cases probably due to
  38. // the calling of relation.lib.php)
  39. $GLOBALS['dbi']->selectDb($GLOBALS['db']);
  40. /**
  41. * Gets tables informations
  42. */
  43. require 'libraries/tbl_info.inc.php';
  44. // define some variables here, for improved syntax in the conditionals
  45. $is_myisam_or_aria = $is_isam = $is_innodb = $is_berkeleydb = false;
  46. $is_aria = $is_pbxt = false;
  47. // set initial value of these variables, based on the current table engine
  48. list($is_myisam_or_aria, $is_innodb, $is_isam,
  49. $is_berkeleydb, $is_aria, $is_pbxt
  50. ) = PMA_setGlobalVariablesForEngine($tbl_storage_engine);
  51. if ($is_aria) {
  52. // the value for transactional can be implicit
  53. // (no create option found, in this case it means 1)
  54. // or explicit (option found with a value of 0 or 1)
  55. // ($transactional may have been set by libraries/tbl_info.inc.php,
  56. // from the $create_options)
  57. $transactional = (isset($transactional) && $transactional == '0')
  58. ? '0'
  59. : '1';
  60. $page_checksum = (isset($page_checksum)) ? $page_checksum : '';
  61. }
  62. $reread_info = false;
  63. $table_alters = array();
  64. /**
  65. * If the table has to be moved to some other database
  66. */
  67. if (isset($_REQUEST['submit_move']) || isset($_REQUEST['submit_copy'])) {
  68. $_message = '';
  69. include_once 'tbl_move_copy.php';
  70. }
  71. /**
  72. * If the table has to be maintained
  73. */
  74. if (isset($_REQUEST['table_maintenance'])) {
  75. include_once 'sql.php';
  76. unset($result);
  77. }
  78. /**
  79. * Updates table comment, type and options if required
  80. */
  81. if (isset($_REQUEST['submitoptions'])) {
  82. $_message = '';
  83. $warning_messages = array();
  84. if (isset($_REQUEST['new_name'])) {
  85. if ($pma_table->rename($_REQUEST['new_name'])) {
  86. $_message .= $pma_table->getLastMessage();
  87. $result = true;
  88. $GLOBALS['table'] = $pma_table->getName();
  89. $reread_info = true;
  90. $reload = true;
  91. } else {
  92. $_message .= $pma_table->getLastError();
  93. $result = false;
  94. }
  95. }
  96. if (! empty($_REQUEST['new_tbl_storage_engine'])
  97. && strtolower($_REQUEST['new_tbl_storage_engine']) !== strtolower($tbl_storage_engine)
  98. ) {
  99. $new_tbl_storage_engine = $_REQUEST['new_tbl_storage_engine'];
  100. // reset the globals for the new engine
  101. list($is_myisam_or_aria, $is_innodb, $is_isam,
  102. $is_berkeleydb, $is_aria, $is_pbxt
  103. ) = PMA_setGlobalVariablesForEngine($new_tbl_storage_engine);
  104. if ($is_aria) {
  105. $transactional = (isset($transactional) && $transactional == '0')
  106. ? '0'
  107. : '1';
  108. $page_checksum = (isset($page_checksum)) ? $page_checksum : '';
  109. }
  110. } else {
  111. $new_tbl_storage_engine = '';
  112. }
  113. $table_alters = PMA_getTableAltersArray(
  114. $is_myisam_or_aria, $is_isam, $pack_keys,
  115. (empty($checksum) ? '0' : '1'),
  116. $is_aria,
  117. ((isset($page_checksum)) ? $page_checksum : ''),
  118. (empty($delay_key_write) ? '0' : '1'),
  119. $is_innodb, $is_pbxt, $row_format,
  120. $new_tbl_storage_engine,
  121. ((isset($transactional) && $transactional == '0') ? '0' : '1'),
  122. $tbl_collation
  123. );
  124. if (count($table_alters) > 0) {
  125. $sql_query = 'ALTER TABLE '
  126. . PMA_Util::backquote($GLOBALS['table']);
  127. $sql_query .= "\r\n" . implode("\r\n", $table_alters);
  128. $sql_query .= ';';
  129. $result .= $GLOBALS['dbi']->query($sql_query) ? true : false;
  130. $reread_info = true;
  131. unset($table_alters);
  132. $warning_messages = PMA_getWarningMessagesArray();
  133. }
  134. }
  135. /**
  136. * Reordering the table has been requested by the user
  137. */
  138. if (isset($_REQUEST['submitorderby']) && ! empty($_REQUEST['order_field'])) {
  139. list($sql_query, $result) = PMA_getQueryAndResultForReorderingTable();
  140. } // end if
  141. /**
  142. * A partition operation has been requested by the user
  143. */
  144. if (isset($_REQUEST['submit_partition'])
  145. && ! empty($_REQUEST['partition_operation'])
  146. ) {
  147. list($sql_query, $result) = PMA_getQueryAndResultForPartition();
  148. } // end if
  149. if ($reread_info) {
  150. // to avoid showing the old value (for example the AUTO_INCREMENT) after
  151. // a change, clear the cache
  152. PMA_Table::$cache = array();
  153. $page_checksum = $checksum = $delay_key_write = 0;
  154. include 'libraries/tbl_info.inc.php';
  155. }
  156. unset($reread_info);
  157. if (isset($result) && empty($message_to_show)) {
  158. // set to success by default, because result set could be empty
  159. // (for example, a table rename)
  160. $_type = 'success';
  161. if (empty($_message)) {
  162. $_message = $result
  163. ? PMA_Message::success(
  164. __('Your SQL query has been executed successfully.')
  165. )
  166. : PMA_Message::error(__('Error'));
  167. // $result should exist, regardless of $_message
  168. $_type = $result ? 'success' : 'error';
  169. if (isset($GLOBALS['ajax_request'])
  170. && $GLOBALS['ajax_request'] == true
  171. ) {
  172. $response = PMA_Response::getInstance();
  173. $response->isSuccess($_message->isSuccess());
  174. $response->addJSON('message', $_message);
  175. $response->addJSON(
  176. 'sql_query', PMA_Util::getMessage(null, $sql_query)
  177. );
  178. exit;
  179. }
  180. }
  181. if (! empty($warning_messages)) {
  182. $_message = new PMA_Message;
  183. $_message->addMessages($warning_messages);
  184. $_message->isError(true);
  185. if ($GLOBALS['ajax_request'] == true) {
  186. $response = PMA_Response::getInstance();
  187. $response->isSuccess(false);
  188. $response->addJSON('message', $_message);
  189. exit;
  190. }
  191. unset($warning_messages);
  192. }
  193. $response->addHTML(
  194. PMA_Util::getMessage($_message, $sql_query, $_type)
  195. );
  196. unset($_message, $_type);
  197. }
  198. $url_params['goto']
  199. = $url_params['back']
  200. = 'tbl_operations.php';
  201. /**
  202. * Get columns names
  203. */
  204. $columns = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $GLOBALS['table']);
  205. /**
  206. * Displays the page
  207. */
  208. $response->addHTML('<div id="boxContainer" data-box-width="300">');
  209. /**
  210. * Order the table
  211. */
  212. $hideOrderTable = false;
  213. // `ALTER TABLE ORDER BY` does not make sense for InnoDB tables that contain
  214. // a user-defined clustered index (PRIMARY KEY or NOT NULL UNIQUE index).
  215. // InnoDB always orders table rows according to such an index if one is present.
  216. if ($tbl_storage_engine == 'INNODB') {
  217. include_once 'libraries/Index.class.php';
  218. $indexes = PMA_Index::getFromTable($GLOBALS['table'], $GLOBALS['db']);
  219. foreach ($indexes as $name => $idx) {
  220. if ($name == 'PRIMARY') {
  221. $hideOrderTable = true;
  222. break;
  223. } elseif (! $idx->getNonUnique()) {
  224. $notNull = true;
  225. foreach ($idx->getColumns() as $column) {
  226. if ($column->getNull()) {
  227. $notNull = false;
  228. break;
  229. }
  230. }
  231. if ($notNull) {
  232. $hideOrderTable = true;
  233. break;
  234. }
  235. }
  236. }
  237. }
  238. if (! $hideOrderTable) {
  239. $response->addHTML(PMA_getHtmlForOrderTheTable($columns));
  240. }
  241. /**
  242. * Move table
  243. */
  244. $response->addHTML(PMA_getHtmlForMoveTable());
  245. if (strstr($show_comment, '; InnoDB free') === false) {
  246. if (strstr($show_comment, 'InnoDB free') === false) {
  247. // only user entered comment
  248. $comment = $show_comment;
  249. } else {
  250. // here we have just InnoDB generated part
  251. $comment = '';
  252. }
  253. } else {
  254. // remove InnoDB comment from end, just the minimal part (*? is non greedy)
  255. $comment = preg_replace('@; InnoDB free:.*?$@', '', $show_comment);
  256. }
  257. // PACK_KEYS: MyISAM or ISAM
  258. // DELAY_KEY_WRITE, CHECKSUM, : MyISAM only
  259. // AUTO_INCREMENT: MyISAM and InnoDB since 5.0.3, PBXT
  260. // Here should be version check for InnoDB, however it is supported
  261. // in >5.0.4, >4.1.12 and >4.0.11, so I decided not to
  262. // check for version
  263. $response->addHTML(
  264. PMA_getTableOptionDiv(
  265. $comment, $tbl_collation, $tbl_storage_engine,
  266. $is_myisam_or_aria, $is_isam, $pack_keys,
  267. $auto_increment,
  268. (empty($delay_key_write) ? '0' : '1'),
  269. ((isset($transactional) && $transactional == '0') ? '0' : '1'),
  270. ((isset($page_checksum)) ? $page_checksum : ''),
  271. $is_innodb, $is_pbxt, $is_aria, (empty($checksum) ? '0' : '1')
  272. )
  273. );
  274. /**
  275. * Copy table
  276. */
  277. $response->addHTML(PMA_getHtmlForCopytable());
  278. /**
  279. * Table maintenance
  280. */
  281. $response->addHTML(
  282. PMA_getHtmlForTableMaintenance(
  283. $is_myisam_or_aria,
  284. $is_innodb,
  285. $is_berkeleydb,
  286. $url_params
  287. )
  288. );
  289. if (! (isset($db_is_system_schema) && $db_is_system_schema)) {
  290. $truncate_table_url_params = array();
  291. $drop_table_url_params = array();
  292. if (! $tbl_is_view
  293. && ! (isset($db_is_system_schema) && $db_is_system_schema)
  294. ) {
  295. $this_sql_query = 'TRUNCATE TABLE '
  296. . PMA_Util::backquote($GLOBALS['table']);
  297. $truncate_table_url_params = array_merge(
  298. $url_params,
  299. array(
  300. 'sql_query' => $this_sql_query,
  301. 'goto' => 'tbl_structure.php',
  302. 'reload' => '1',
  303. 'message_to_show' => sprintf(
  304. __('Table %s has been emptied.'),
  305. htmlspecialchars($table)
  306. ),
  307. )
  308. );
  309. }
  310. if (! (isset($db_is_system_schema) && $db_is_system_schema)) {
  311. $this_sql_query = 'DROP TABLE '
  312. . PMA_Util::backquote($GLOBALS['table']);
  313. $drop_table_url_params = array_merge(
  314. $url_params,
  315. array(
  316. 'sql_query' => $this_sql_query,
  317. 'goto' => 'db_operations.php',
  318. 'reload' => '1',
  319. 'purge' => '1',
  320. 'message_to_show' => sprintf(
  321. ($tbl_is_view
  322. ? __('View %s has been dropped.')
  323. : __('Table %s has been dropped.')
  324. ),
  325. htmlspecialchars($table)
  326. ),
  327. // table name is needed to avoid running
  328. // PMA_relationsCleanupDatabase() on the whole db later
  329. 'table' => $GLOBALS['table'],
  330. )
  331. );
  332. }
  333. $response->addHTML(
  334. PMA_getHtmlForDeleteDataOrTable(
  335. $truncate_table_url_params,
  336. $drop_table_url_params
  337. )
  338. );
  339. }
  340. if (PMA_Partition::havePartitioning()) {
  341. $partition_names = PMA_Partition::getPartitionNames($db, $table);
  342. // show the Partition maintenance section only if we detect a partition
  343. if (! is_null($partition_names[0])) {
  344. $response->addHTML(
  345. PMA_getHtmlForPartitionMaintenance($partition_names, $url_params)
  346. );
  347. } // end if
  348. } // end if
  349. unset($partition_names);
  350. // Referential integrity check
  351. // The Referential integrity check was intended for the non-InnoDB
  352. // tables for which the relations are defined in pmadb
  353. // so I assume that if the current table is InnoDB, I don't display
  354. // this choice (InnoDB maintains integrity by itself)
  355. if ($cfgRelation['relwork'] && ! $is_innodb) {
  356. $GLOBALS['dbi']->selectDb($GLOBALS['db']);
  357. $foreign = PMA_getForeigners($GLOBALS['db'], $GLOBALS['table']);
  358. if ($foreign) {
  359. $response->addHTML(
  360. PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params)
  361. );
  362. } // end if ($foreign)
  363. } // end if (!empty($cfg['Server']['relation']))
  364. $response->addHTML('</div>');
  365. ?>