PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/StorageEngine.php

https://gitlab.com/trungthao379/phpmyadmin
PHP | 463 lines | 285 code | 40 blank | 138 comment | 34 complexity | 78a7f11ac2ee9f8a1dff46825d5778cd MD5 | raw file
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Library for extracting information about the available storage engines
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PMA\libraries;
  9. /**
  10. * defines
  11. */
  12. use PMA\libraries\engines\Bdb;
  13. use PMA\libraries\engines\Berkeleydb;
  14. use PMA\libraries\engines\Binlog;
  15. use PMA\libraries\engines\Innobase;
  16. use PMA\libraries\engines\Innodb;
  17. use PMA\libraries\engines\Memory;
  18. use PMA\libraries\engines\Merge;
  19. use PMA\libraries\engines\Mrg_Myisam;
  20. use PMA\libraries\engines\Myisam;
  21. use PMA\libraries\engines\Ndbcluster;
  22. use PMA\libraries\engines\Pbxt;
  23. use PMA\libraries\engines\Performance_Schema;
  24. define('PMA_ENGINE_SUPPORT_NO', 0);
  25. define('PMA_ENGINE_SUPPORT_DISABLED', 1);
  26. define('PMA_ENGINE_SUPPORT_YES', 2);
  27. define('PMA_ENGINE_SUPPORT_DEFAULT', 3);
  28. define('PMA_ENGINE_DETAILS_TYPE_PLAINTEXT', 0);
  29. define('PMA_ENGINE_DETAILS_TYPE_SIZE', 1);
  30. define('PMA_ENGINE_DETAILS_TYPE_NUMERIC', 2); //Has no effect yet...
  31. define('PMA_ENGINE_DETAILS_TYPE_BOOLEAN', 3); // 'ON' or 'OFF'
  32. /**
  33. * Base Storage Engine Class
  34. *
  35. * @package PhpMyAdmin
  36. */
  37. class StorageEngine
  38. {
  39. /**
  40. * @var string engine name
  41. */
  42. var $engine = 'dummy';
  43. /**
  44. * @var string engine title/description
  45. */
  46. var $title = 'PMA Dummy Engine Class';
  47. /**
  48. * @var string engine lang description
  49. */
  50. var $comment
  51. = 'If you read this text inside phpMyAdmin, something went wrong...';
  52. /**
  53. * @var integer engine supported by current server
  54. */
  55. var $support = PMA_ENGINE_SUPPORT_NO;
  56. /**
  57. * Constructor
  58. *
  59. * @param string $engine The engine ID
  60. */
  61. public function __construct($engine)
  62. {
  63. $storage_engines = StorageEngine::getStorageEngines();
  64. if (! empty($storage_engines[$engine])) {
  65. $this->engine = $engine;
  66. $this->title = $storage_engines[$engine]['Engine'];
  67. $this->comment = (isset($storage_engines[$engine]['Comment'])
  68. ? $storage_engines[$engine]['Comment']
  69. : '');
  70. switch ($storage_engines[$engine]['Support']) {
  71. case 'DEFAULT':
  72. $this->support = PMA_ENGINE_SUPPORT_DEFAULT;
  73. break;
  74. case 'YES':
  75. $this->support = PMA_ENGINE_SUPPORT_YES;
  76. break;
  77. case 'DISABLED':
  78. $this->support = PMA_ENGINE_SUPPORT_DISABLED;
  79. break;
  80. case 'NO':
  81. default:
  82. $this->support = PMA_ENGINE_SUPPORT_NO;
  83. }
  84. }
  85. }
  86. /**
  87. * Returns array of storage engines
  88. *
  89. * @static
  90. * @staticvar array $storage_engines storage engines
  91. * @access public
  92. * @return string[] array of storage engines
  93. */
  94. static public function getStorageEngines()
  95. {
  96. static $storage_engines = null;
  97. if (null == $storage_engines) {
  98. $storage_engines
  99. = $GLOBALS['dbi']->fetchResult('SHOW STORAGE ENGINES', 'Engine');
  100. if (PMA_MYSQL_INT_VERSION >= 50708) {
  101. $disabled = Util::cacheGet(
  102. 'disabled_storage_engines',
  103. function () {
  104. return $GLOBALS['dbi']->fetchValue(
  105. 'SELECT @@disabled_storage_engines'
  106. );
  107. }
  108. );
  109. foreach (explode(",", $disabled) as $engine) {
  110. if (isset($storage_engines[$engine])) {
  111. $storage_engines[$engine]['Support'] = 'DISABLED';
  112. }
  113. }
  114. }
  115. }
  116. return $storage_engines;
  117. }
  118. /**
  119. * Returns HTML code for storage engine select box
  120. *
  121. * @param string $name The name of the select form element
  122. * @param string $id The ID of the form field
  123. * @param string $selected The selected engine
  124. * @param boolean $offerUnavailableEngines Should unavailable storage
  125. * engines be offered?
  126. * @param boolean $addEmpty Whether to provide empty option
  127. *
  128. * @static
  129. * @return string html selectbox
  130. */
  131. static public function getHtmlSelect(
  132. $name = 'engine', $id = null,
  133. $selected = null, $offerUnavailableEngines = false,
  134. $addEmpty = false
  135. ) {
  136. $selected = mb_strtolower($selected);
  137. $output = '<select name="' . $name . '"'
  138. . (empty($id) ? '' : ' id="' . $id . '"') . '>' . "\n";
  139. if ($addEmpty) {
  140. $output .= '<option value=""></option>';
  141. }
  142. foreach (StorageEngine::getStorageEngines() as $key => $details) {
  143. // Don't show PERFORMANCE_SCHEMA engine (MySQL 5.5)
  144. if (! $offerUnavailableEngines
  145. && ($details['Support'] == 'NO'
  146. || $details['Support'] == 'DISABLED'
  147. || $details['Engine'] == 'PERFORMANCE_SCHEMA')
  148. ) {
  149. continue;
  150. }
  151. $output .= ' <option value="' . htmlspecialchars($key) . '"'
  152. . (empty($details['Comment'])
  153. ? '' : ' title="' . htmlspecialchars($details['Comment']) . '"')
  154. . (mb_strtolower($key) == $selected
  155. || (empty($selected) && $details['Support'] == 'DEFAULT' && ! $addEmpty)
  156. ? ' selected="selected"' : '')
  157. . '>' . "\n"
  158. . ' ' . htmlspecialchars($details['Engine']) . "\n"
  159. . ' </option>' . "\n";
  160. }
  161. $output .= '</select>' . "\n";
  162. return $output;
  163. }
  164. /**
  165. * Loads the corresponding engine plugin, if available.
  166. *
  167. * @param string $engine The engine ID
  168. *
  169. * @return StorageEngine The engine plugin
  170. * @static
  171. */
  172. static public function getEngine($engine)
  173. {
  174. switch(strtolower($engine)) {
  175. case 'bdb':
  176. return new Bdb($engine);
  177. case 'berkeleydb':
  178. return new Berkeleydb($engine);
  179. case 'binlog':
  180. return new Binlog($engine);
  181. case 'innobase':
  182. return new Innobase($engine);
  183. case 'innodb':
  184. return new Innodb($engine);
  185. case 'memory':
  186. return new Memory($engine);
  187. case 'merge':
  188. return new Merge($engine);
  189. case 'mrg_myisam':
  190. return new Mrg_Myisam($engine);
  191. case 'myisam':
  192. return new Myisam($engine);
  193. case 'ndbcluster':
  194. return new Ndbcluster($engine);
  195. case 'pbxt':
  196. return new Pbxt($engine);
  197. case 'performance_schema':
  198. return new Performance_Schema($engine);
  199. default:
  200. return new StorageEngine($engine);
  201. }
  202. }
  203. /**
  204. * Returns true if given engine name is supported/valid, otherwise false
  205. *
  206. * @param string $engine name of engine
  207. *
  208. * @static
  209. * @return boolean whether $engine is valid or not
  210. */
  211. static public function isValid($engine)
  212. {
  213. if ($engine == "PBMS") {
  214. return true;
  215. }
  216. $storage_engines = StorageEngine::getStorageEngines();
  217. return isset($storage_engines[$engine]);
  218. }
  219. /**
  220. * Returns as HTML table of the engine's server variables
  221. *
  222. * @return string The table that was generated based on the retrieved
  223. * information
  224. */
  225. public function getHtmlVariables()
  226. {
  227. $odd_row = false;
  228. $ret = '';
  229. foreach ($this->getVariablesStatus() as $details) {
  230. $ret .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
  231. . ' <td>' . "\n";
  232. if (! empty($details['desc'])) {
  233. $ret .= ' '
  234. . Util::showHint($details['desc'])
  235. . "\n";
  236. }
  237. $ret .= ' </td>' . "\n"
  238. . ' <th>' . htmlspecialchars($details['title']) . '</th>'
  239. . "\n"
  240. . ' <td class="value">';
  241. switch ($details['type']) {
  242. case PMA_ENGINE_DETAILS_TYPE_SIZE:
  243. $parsed_size = $this->resolveTypeSize($details['value']);
  244. $ret .= $parsed_size[0] . '&nbsp;' . $parsed_size[1];
  245. unset($parsed_size);
  246. break;
  247. case PMA_ENGINE_DETAILS_TYPE_NUMERIC:
  248. $ret .= Util::formatNumber($details['value']) . ' ';
  249. break;
  250. default:
  251. $ret .= htmlspecialchars($details['value']) . ' ';
  252. }
  253. $ret .= '</td>' . "\n"
  254. . '</tr>' . "\n";
  255. $odd_row = ! $odd_row;
  256. }
  257. if (! $ret) {
  258. $ret = '<p>' . "\n"
  259. . ' '
  260. . __(
  261. 'There is no detailed status information available for this '
  262. . 'storage engine.'
  263. )
  264. . "\n"
  265. . '</p>' . "\n";
  266. } else {
  267. $ret = '<table class="data">' . "\n" . $ret . '</table>' . "\n";
  268. }
  269. return $ret;
  270. }
  271. /**
  272. * Returns the engine specific handling for
  273. * PMA_ENGINE_DETAILS_TYPE_SIZE type variables.
  274. *
  275. * This function should be overridden when
  276. * PMA_ENGINE_DETAILS_TYPE_SIZE type needs to be
  277. * handled differently for a particular engine.
  278. *
  279. * @param integer $value Value to format
  280. *
  281. * @return string the formatted value and its unit
  282. */
  283. public function resolveTypeSize($value)
  284. {
  285. return Util::formatByteDown($value);
  286. }
  287. /**
  288. * Returns array with detailed info about engine specific server variables
  289. *
  290. * @return array array with detailed info about specific engine server variables
  291. */
  292. public function getVariablesStatus()
  293. {
  294. $variables = $this->getVariables();
  295. $like = $this->getVariablesLikePattern();
  296. if ($like) {
  297. $like = " LIKE '" . $like . "' ";
  298. } else {
  299. $like = '';
  300. }
  301. $mysql_vars = array();
  302. $sql_query = 'SHOW GLOBAL VARIABLES ' . $like . ';';
  303. $res = $GLOBALS['dbi']->query($sql_query);
  304. while ($row = $GLOBALS['dbi']->fetchAssoc($res)) {
  305. if (isset($variables[$row['Variable_name']])) {
  306. $mysql_vars[$row['Variable_name']]
  307. = $variables[$row['Variable_name']];
  308. } elseif (! $like
  309. && mb_strpos(mb_strtolower($row['Variable_name']), mb_strtolower($this->engine)) !== 0
  310. ) {
  311. continue;
  312. }
  313. $mysql_vars[$row['Variable_name']]['value'] = $row['Value'];
  314. if (empty($mysql_vars[$row['Variable_name']]['title'])) {
  315. $mysql_vars[$row['Variable_name']]['title'] = $row['Variable_name'];
  316. }
  317. if (! isset($mysql_vars[$row['Variable_name']]['type'])) {
  318. $mysql_vars[$row['Variable_name']]['type']
  319. = PMA_ENGINE_DETAILS_TYPE_PLAINTEXT;
  320. }
  321. }
  322. $GLOBALS['dbi']->freeResult($res);
  323. return $mysql_vars;
  324. }
  325. /**
  326. * Reveals the engine's title
  327. *
  328. * @return string The title
  329. */
  330. public function getTitle()
  331. {
  332. return $this->title;
  333. }
  334. /**
  335. * Fetches the server's comment about this engine
  336. *
  337. * @return string The comment
  338. */
  339. public function getComment()
  340. {
  341. return $this->comment;
  342. }
  343. /**
  344. * Information message on whether this storage engine is supported
  345. *
  346. * @return string The localized message.
  347. */
  348. public function getSupportInformationMessage()
  349. {
  350. switch ($this->support) {
  351. case PMA_ENGINE_SUPPORT_DEFAULT:
  352. $message = __('%s is the default storage engine on this MySQL server.');
  353. break;
  354. case PMA_ENGINE_SUPPORT_YES:
  355. $message = __('%s is available on this MySQL server.');
  356. break;
  357. case PMA_ENGINE_SUPPORT_DISABLED:
  358. $message = __('%s has been disabled for this MySQL server.');
  359. break;
  360. case PMA_ENGINE_SUPPORT_NO:
  361. default:
  362. $message = __(
  363. 'This MySQL server does not support the %s storage engine.'
  364. );
  365. }
  366. return sprintf($message, htmlspecialchars($this->title));
  367. }
  368. /**
  369. * Generates a list of MySQL variables that provide information about this
  370. * engine. This function should be overridden when extending this class
  371. * for a particular engine.
  372. *
  373. * @return array The list of variables.
  374. */
  375. public function getVariables()
  376. {
  377. return array();
  378. }
  379. /**
  380. * Returns string with filename for the MySQL helppage
  381. * about this storage engine
  382. *
  383. * @return string MySQL help page filename
  384. */
  385. public function getMysqlHelpPage()
  386. {
  387. return $this->engine . '-storage-engine';
  388. }
  389. /**
  390. * Returns the pattern to be used in the query for SQL variables
  391. * related to the storage engine
  392. *
  393. * @return string SQL query LIKE pattern
  394. */
  395. public function getVariablesLikePattern()
  396. {
  397. return '';
  398. }
  399. /**
  400. * Returns a list of available information pages with labels
  401. *
  402. * @return string[] The list
  403. */
  404. public function getInfoPages()
  405. {
  406. return array();
  407. }
  408. /**
  409. * Generates the requested information page
  410. *
  411. * @param string $id page id
  412. *
  413. * @return string html output
  414. */
  415. public function getPage($id)
  416. {
  417. if (! array_key_exists($id, $this->getInfoPages())) {
  418. return '';
  419. }
  420. $id = 'getPage' . $id;
  421. return $this->$id();
  422. }
  423. }