StorageEngine.php 13 KB

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