schemaupdater.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * Database schema utilities
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category Database
  23. * @package StatusNet
  24. * @author Evan Prodromou <evan@status.net>
  25. * @copyright 2009 StatusNet, Inc.
  26. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  27. * @link http://status.net/
  28. */
  29. if (!defined('GNUSOCIAL')) { exit(1); }
  30. class SchemaUpdater
  31. {
  32. public function __construct($schema)
  33. {
  34. $this->schema = $schema;
  35. $this->checksums = $this->getChecksums();
  36. }
  37. /**
  38. * @param string $tableName
  39. * @param array $tableDef
  40. */
  41. public function register($tableName, array $tableDef)
  42. {
  43. // Check if the table we're registering is related to a Managed_DataObject
  44. if (is_a(ucfirst($tableName), 'Managed_DataObject', true)) {
  45. call_user_func("{$tableName}::beforeSchemaUpdate");
  46. }
  47. $this->tables[$tableName] = $tableDef;
  48. }
  49. /**
  50. * Go ping em!
  51. *
  52. * @fixme handle tables that belong on different database servers...?
  53. */
  54. public function checkSchema()
  55. {
  56. $checksums = $this->checksums;
  57. foreach ($this->tables as $table => $def) {
  58. $checksum = $this->checksum($def);
  59. if (empty($checksums[$table])) {
  60. common_log(LOG_DEBUG, "No previous schema_version for $table: updating to $checksum");
  61. } else if ($checksums[$table] == $checksum) {
  62. common_log(LOG_DEBUG, "Last schema_version for $table up to date: $checksum");
  63. continue;
  64. } else {
  65. common_log(LOG_DEBUG, "Last schema_version for $table is {$checksums[$table]}: updating to $checksum");
  66. }
  67. //$this->conn->query('BEGIN');
  68. $this->schema->ensureTable($table, $def);
  69. $this->saveChecksum($table, $checksum);
  70. //$this->conn->commit();
  71. }
  72. }
  73. /**
  74. * Calculate a checksum for this table definition array.
  75. *
  76. * @param array $def
  77. * @return string
  78. */
  79. public function checksum(array $def)
  80. {
  81. $flat = serialize($def);
  82. return sha1($flat);
  83. }
  84. /**
  85. * Pull all known table checksums into an array for easy lookup.
  86. *
  87. * @return array: associative array of table names to checksum strings
  88. */
  89. protected function getChecksums()
  90. {
  91. $checksums = array();
  92. try {
  93. $sv = new Schema_version();
  94. $sv->find();
  95. while ($sv->fetch()) {
  96. $checksums[$sv->table_name] = $sv->checksum;
  97. }
  98. return $checksums;
  99. } catch (Exception $e) {
  100. // no dice!
  101. common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
  102. }
  103. return $checksums;
  104. }
  105. /**
  106. * Save or update current available checksums.
  107. *
  108. * @param string $table
  109. * @param string $checksum
  110. */
  111. protected function saveChecksum($table, $checksum)
  112. {
  113. try {
  114. $sv = new Schema_version();
  115. $sv->table_name = $table;
  116. $sv->checksum = $checksum;
  117. $sv->modified = common_sql_now();
  118. if (isset($this->checksums[$table])) {
  119. $sv->update();
  120. } else {
  121. $sv->insert();
  122. }
  123. } catch (Exception $e) {
  124. // no dice!
  125. common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet.");
  126. }
  127. $this->checksums[$table] = $checksum;
  128. }
  129. }