Changelog.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Mview\View;
  7. use Magento\Framework\Phrase;
  8. class Changelog implements ChangelogInterface
  9. {
  10. /**
  11. * Suffix for changelog table
  12. */
  13. const NAME_SUFFIX = 'cl';
  14. /**
  15. * Column name of changelog entity
  16. */
  17. const COLUMN_NAME = 'entity_id';
  18. /**
  19. * Database connection
  20. *
  21. * @var \Magento\Framework\DB\Adapter\AdapterInterface
  22. */
  23. protected $connection;
  24. /**
  25. * View Id identifier
  26. *
  27. * @var string
  28. */
  29. protected $viewId;
  30. /**
  31. * @var \Magento\Framework\App\ResourceConnection
  32. */
  33. protected $resource;
  34. /**
  35. * @param \Magento\Framework\App\ResourceConnection $resource
  36. */
  37. public function __construct(\Magento\Framework\App\ResourceConnection $resource)
  38. {
  39. $this->connection = $resource->getConnection();
  40. $this->resource = $resource;
  41. $this->checkConnection();
  42. }
  43. /**
  44. * Check DB connection
  45. *
  46. * @return void
  47. * @throws \Exception
  48. */
  49. protected function checkConnection()
  50. {
  51. if (!$this->connection) {
  52. throw new \Exception("The write connection to the database isn't available. Please try again later.");
  53. }
  54. }
  55. /**
  56. * Create changelog table
  57. *
  58. * @return void
  59. * @throws \Exception
  60. */
  61. public function create()
  62. {
  63. $changelogTableName = $this->resource->getTableName($this->getName());
  64. if (!$this->connection->isTableExists($changelogTableName)) {
  65. $table = $this->connection->newTable(
  66. $changelogTableName
  67. )->addColumn(
  68. 'version_id',
  69. \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
  70. null,
  71. ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
  72. 'Version ID'
  73. )->addColumn(
  74. $this->getColumnName(),
  75. \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
  76. null,
  77. ['unsigned' => true, 'nullable' => false, 'default' => '0'],
  78. 'Entity ID'
  79. );
  80. $this->connection->createTable($table);
  81. }
  82. }
  83. /**
  84. * Drop changelog table
  85. *
  86. * @return void
  87. * @throws ChangelogTableNotExistsException
  88. */
  89. public function drop()
  90. {
  91. $changelogTableName = $this->resource->getTableName($this->getName());
  92. if (!$this->connection->isTableExists($changelogTableName)) {
  93. throw new ChangelogTableNotExistsException(new Phrase("Table %1 does not exist", [$changelogTableName]));
  94. }
  95. $this->connection->dropTable($changelogTableName);
  96. }
  97. /**
  98. * Clear changelog table by version_id
  99. *
  100. * @param int $versionId
  101. * @return boolean
  102. * @throws ChangelogTableNotExistsException
  103. */
  104. public function clear($versionId)
  105. {
  106. $changelogTableName = $this->resource->getTableName($this->getName());
  107. if (!$this->connection->isTableExists($changelogTableName)) {
  108. throw new ChangelogTableNotExistsException(new Phrase("Table %1 does not exist", [$changelogTableName]));
  109. }
  110. $this->connection->delete($changelogTableName, ['version_id < ?' => (int)$versionId]);
  111. return true;
  112. }
  113. /**
  114. * Retrieve entity ids by range [$fromVersionId..$toVersionId]
  115. *
  116. * @param int $fromVersionId
  117. * @param int $toVersionId
  118. * @return int[]
  119. * @throws ChangelogTableNotExistsException
  120. */
  121. public function getList($fromVersionId, $toVersionId)
  122. {
  123. $changelogTableName = $this->resource->getTableName($this->getName());
  124. if (!$this->connection->isTableExists($changelogTableName)) {
  125. throw new ChangelogTableNotExistsException(new Phrase("Table %1 does not exist", [$changelogTableName]));
  126. }
  127. $select = $this->connection->select()->distinct(
  128. true
  129. )->from(
  130. $changelogTableName,
  131. [$this->getColumnName()]
  132. )->where(
  133. 'version_id > ?',
  134. (int)$fromVersionId
  135. )->where(
  136. 'version_id <= ?',
  137. (int)$toVersionId
  138. );
  139. return $this->connection->fetchCol($select);
  140. }
  141. /**
  142. * Get maximum version_id from changelog
  143. * @return int
  144. * @throws ChangelogTableNotExistsException
  145. * @throws \Exception
  146. */
  147. public function getVersion()
  148. {
  149. $changelogTableName = $this->resource->getTableName($this->getName());
  150. if (!$this->connection->isTableExists($changelogTableName)) {
  151. throw new ChangelogTableNotExistsException(new Phrase("Table %1 does not exist", [$changelogTableName]));
  152. }
  153. $row = $this->connection->fetchRow('SHOW TABLE STATUS LIKE ?', [$changelogTableName]);
  154. if (isset($row['Auto_increment'])) {
  155. return (int)$row['Auto_increment'] - 1;
  156. } else {
  157. throw new \Exception("Table status for `{$changelogTableName}` is incorrect. Can`t fetch version id.");
  158. }
  159. }
  160. /**
  161. * Get changlog name
  162. *
  163. * Build a changelog name by concatenating view identifier and changelog name suffix.
  164. *
  165. * @throws \Exception
  166. * @return string
  167. */
  168. public function getName()
  169. {
  170. if (strlen($this->viewId) == 0) {
  171. throw new \Exception("View's identifier is not set");
  172. }
  173. return $this->viewId . '_' . self::NAME_SUFFIX;
  174. }
  175. /**
  176. * Get changlog entity column name
  177. *
  178. * @return string
  179. */
  180. public function getColumnName()
  181. {
  182. return self::COLUMN_NAME;
  183. }
  184. /**
  185. * Set view's identifier
  186. *
  187. * @param string $viewId
  188. * @return Changelog
  189. */
  190. public function setViewId($viewId)
  191. {
  192. $this->viewId = $viewId;
  193. return $this;
  194. }
  195. /**
  196. * @return string
  197. */
  198. public function getViewId()
  199. {
  200. return $this->viewId;
  201. }
  202. }