DatabaseDAO.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /**
  3. * This class is used to test database is well-constructed.
  4. */
  5. class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
  6. //MySQL error codes
  7. const ER_BAD_FIELD_ERROR = '42S22';
  8. const ER_BAD_TABLE_ERROR = '42S02';
  9. const ER_TRUNCATED_WRONG_VALUE_FOR_FIELD = '1366';
  10. //MySQL InnoDB maximum index length for UTF8MB4
  11. //https://dev.mysql.com/doc/refman/8.0/en/innodb-restrictions.html
  12. const LENGTH_INDEX_UNICODE = 191;
  13. public function tablesAreCorrect() {
  14. $sql = 'SHOW TABLES';
  15. $stm = $this->bd->prepare($sql);
  16. $stm->execute();
  17. $res = $stm->fetchAll(PDO::FETCH_ASSOC);
  18. $tables = array(
  19. $this->prefix . 'category' => false,
  20. $this->prefix . 'feed' => false,
  21. $this->prefix . 'entry' => false,
  22. $this->prefix . 'entrytmp' => false,
  23. $this->prefix . 'tag' => false,
  24. $this->prefix . 'entrytag' => false,
  25. );
  26. foreach ($res as $value) {
  27. $tables[array_pop($value)] = true;
  28. }
  29. return count(array_keys($tables, true, true)) == count($tables);
  30. }
  31. public function getSchema($table) {
  32. $sql = 'DESC ' . $this->prefix . $table;
  33. $stm = $this->bd->prepare($sql);
  34. $stm->execute();
  35. return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC));
  36. }
  37. public function checkTable($table, $schema) {
  38. $columns = $this->getSchema($table);
  39. $ok = (count($columns) == count($schema));
  40. foreach ($columns as $c) {
  41. $ok &= in_array($c['name'], $schema);
  42. }
  43. return $ok;
  44. }
  45. public function categoryIsCorrect() {
  46. return $this->checkTable('category', array(
  47. 'id', 'name',
  48. ));
  49. }
  50. public function feedIsCorrect() {
  51. return $this->checkTable('feed', array(
  52. 'id', 'url', 'category', 'name', 'website', 'description', 'lastUpdate',
  53. 'priority', 'pathEntries', 'httpAuth', 'error', 'keep_history', 'ttl', 'attributes',
  54. 'cache_nbEntries', 'cache_nbUnreads',
  55. ));
  56. }
  57. public function entryIsCorrect() {
  58. return $this->checkTable('entry', array(
  59. 'id', 'guid', 'title', 'author', 'content_bin', 'link', 'date', 'lastSeen', 'hash', 'is_read',
  60. 'is_favorite', 'id_feed', 'tags',
  61. ));
  62. }
  63. public function entrytmpIsCorrect() {
  64. return $this->checkTable('entrytmp', array(
  65. 'id', 'guid', 'title', 'author', 'content_bin', 'link', 'date', 'lastSeen', 'hash', 'is_read',
  66. 'is_favorite', 'id_feed', 'tags',
  67. ));
  68. }
  69. public function tagIsCorrect() {
  70. return $this->checkTable('tag', array(
  71. 'id', 'name', 'attributes',
  72. ));
  73. }
  74. public function entrytagIsCorrect() {
  75. return $this->checkTable('entrytag', array(
  76. 'id_tag', 'id_entry',
  77. ));
  78. }
  79. public function daoToSchema($dao) {
  80. return array(
  81. 'name' => $dao['Field'],
  82. 'type' => strtolower($dao['Type']),
  83. 'notnull' => (bool)$dao['Null'],
  84. 'default' => $dao['Default'],
  85. );
  86. }
  87. public function listDaoToSchema($listDAO) {
  88. $list = array();
  89. foreach ($listDAO as $dao) {
  90. $list[] = $this->daoToSchema($dao);
  91. }
  92. return $list;
  93. }
  94. public function size($all = false) {
  95. $db = FreshRSS_Context::$system_conf->db;
  96. $sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema=?'; //MySQL
  97. $values = array($db['base']);
  98. if (!$all) {
  99. $sql .= ' AND table_name LIKE ?';
  100. $values[] = $this->prefix . '%';
  101. }
  102. $stm = $this->bd->prepare($sql);
  103. $stm->execute($values);
  104. $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
  105. return $res[0];
  106. }
  107. public function optimize() {
  108. $ok = true;
  109. $tables = array('category', 'feed', 'entry', 'entrytmp', 'tag', 'entrytag');
  110. foreach ($tables as $table) {
  111. $sql = 'OPTIMIZE TABLE `' . $this->prefix . $table . '`'; //MySQL
  112. $stm = $this->bd->prepare($sql);
  113. $ok &= $stm != false;
  114. if ($stm) {
  115. $ok &= $stm->execute();
  116. }
  117. }
  118. return $ok;
  119. }
  120. }