1010
1111use Magento \Framework \App \ResourceConnection ;
1212use Magento \Framework \DB \Ddl \Trigger ;
13+ use Magento \Framework \DB \Ddl \TriggerFactory ;
14+ use Magento \Framework \Mview \ViewInterface ;
1315
1416class Subscription implements SubscriptionInterface
1517{
@@ -21,12 +23,12 @@ class Subscription implements SubscriptionInterface
2123 protected $ connection ;
2224
2325 /**
24- * @var \Magento\Framework\DB\Ddl\ TriggerFactory
26+ * @var TriggerFactory
2527 */
2628 protected $ triggerFactory ;
2729
2830 /**
29- * @var \Magento\Framework\Mview\View\ CollectionInterface
31+ * @var CollectionInterface
3032 */
3133 protected $ viewCollection ;
3234
@@ -57,21 +59,32 @@ class Subscription implements SubscriptionInterface
5759 */
5860 protected $ resource ;
5961
62+ /**
63+ * List of columns that can be updated in a subscribed table
64+ * without creating a new change log entry
65+ *
66+ * @var array
67+ */
68+ private $ ignoredUpdateColumns = [];
69+
6070 /**
6171 * @param ResourceConnection $resource
62- * @param \Magento\Framework\DB\Ddl\ TriggerFactory $triggerFactory
63- * @param \Magento\Framework\Mview\View\ CollectionInterface $viewCollection
64- * @param \Magento\Framework\Mview\ ViewInterface $view
72+ * @param TriggerFactory $triggerFactory
73+ * @param CollectionInterface $viewCollection
74+ * @param ViewInterface $view
6575 * @param string $tableName
6676 * @param string $columnName
77+ * @param array $ignoredUpdateColumns
78+ * @throws \DomainException
6779 */
6880 public function __construct (
6981 ResourceConnection $ resource ,
70- \ Magento \ Framework \ DB \ Ddl \ TriggerFactory $ triggerFactory ,
71- \ Magento \ Framework \ Mview \ View \ CollectionInterface $ viewCollection ,
72- \ Magento \ Framework \ Mview \ ViewInterface $ view ,
82+ TriggerFactory $ triggerFactory ,
83+ CollectionInterface $ viewCollection ,
84+ ViewInterface $ view ,
7385 $ tableName ,
74- $ columnName
86+ $ columnName ,
87+ array $ ignoredUpdateColumns = []
7588 ) {
7689 $ this ->connection = $ resource ->getConnection ();
7790 $ this ->triggerFactory = $ triggerFactory ;
@@ -80,12 +93,14 @@ public function __construct(
8093 $ this ->tableName = $ tableName ;
8194 $ this ->columnName = $ columnName ;
8295 $ this ->resource = $ resource ;
96+ $ this ->ignoredUpdateColumns = $ ignoredUpdateColumns ;
8397 }
8498
8599 /**
86- * Create subsciption
100+ * Create subscription
87101 *
88- * @return \Magento\Framework\Mview\View\SubscriptionInterface
102+ * @return SubscriptionInterface
103+ * @throws \InvalidArgumentException
89104 */
90105 public function create ()
91106 {
@@ -102,7 +117,7 @@ public function create()
102117
103118 // Add statements for linked views
104119 foreach ($ this ->getLinkedViews () as $ view ) {
105- /** @var \Magento\Framework\Mview\ ViewInterface $view */
120+ /** @var ViewInterface $view */
106121 $ trigger ->addStatement ($ this ->buildStatement ($ event , $ view ->getChangelog ()));
107122 }
108123
@@ -116,7 +131,8 @@ public function create()
116131 /**
117132 * Remove subscription
118133 *
119- * @return \Magento\Framework\Mview\View\SubscriptionInterface
134+ * @return SubscriptionInterface
135+ * @throws \InvalidArgumentException
120136 */
121137 public function remove ()
122138 {
@@ -131,7 +147,7 @@ public function remove()
131147
132148 // Add statements for linked views
133149 foreach ($ this ->getLinkedViews () as $ view ) {
134- /** @var \Magento\Framework\Mview\ ViewInterface $view */
150+ /** @var ViewInterface $view */
135151 $ trigger ->addStatement ($ this ->buildStatement ($ event , $ view ->getChangelog ()));
136152 }
137153
@@ -154,10 +170,10 @@ public function remove()
154170 protected function getLinkedViews ()
155171 {
156172 if (!$ this ->linkedViews ) {
157- $ viewList = $ this ->viewCollection ->getViewsByStateMode (\ Magento \ Framework \ Mview \ View \ StateInterface::MODE_ENABLED );
173+ $ viewList = $ this ->viewCollection ->getViewsByStateMode (StateInterface::MODE_ENABLED );
158174
159175 foreach ($ viewList as $ view ) {
160- /** @var \Magento\Framework\Mview\ ViewInterface $view */
176+ /** @var ViewInterface $view */
161177 // Skip the current view
162178 if ($ view ->getId () == $ this ->getView ()->getId ()) {
163179 continue ;
@@ -175,35 +191,58 @@ protected function getLinkedViews()
175191 }
176192
177193 /**
178- * Build trigger statement for INSER , UPDATE, DELETE events
194+ * Build trigger statement for INSERT , UPDATE, DELETE events
179195 *
180196 * @param string $event
181- * @param \Magento\Framework\Mview\View\ ChangelogInterface $changelog
197+ * @param ChangelogInterface $changelog
182198 * @return string
183199 */
184200 protected function buildStatement ($ event , $ changelog )
185201 {
186202 switch ($ event ) {
187203 case Trigger::EVENT_INSERT :
204+ $ trigger = 'INSERT IGNORE INTO %s (%s) VALUES (NEW.%s); ' ;
205+ break ;
206+
188207 case Trigger::EVENT_UPDATE :
189- return sprintf (
190- "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s); " ,
191- $ this ->connection ->quoteIdentifier ($ this ->resource ->getTableName ($ changelog ->getName ())),
192- $ this ->connection ->quoteIdentifier ($ changelog ->getColumnName ()),
193- $ this ->connection ->quoteIdentifier ($ this ->getColumnName ())
194- );
208+ $ trigger = 'INSERT IGNORE INTO %s (%s) VALUES (NEW.%s); ' ;
209+
210+ if ($ this ->connection ->isTableExists ($ this ->getTableName ())
211+ && $ describe = $ this ->connection ->describeTable ($ this ->getTableName ())
212+ ) {
213+ $ columnNames = array_column ($ describe , 'COLUMN_NAME ' );
214+ $ columnNames = array_diff ($ columnNames , $ this ->ignoredUpdateColumns );
215+ if ($ columnNames ) {
216+ $ columns = [];
217+ foreach ($ columnNames as $ columnName ) {
218+ $ columns [] = sprintf (
219+ 'NEW.%1$s != OLD.%1$s ' ,
220+ $ this ->connection ->quoteIdentifier ($ columnName )
221+ );
222+ }
223+ $ trigger = sprintf (
224+ "IF (%s) THEN %s END IF; " ,
225+ implode (' OR ' , $ columns ),
226+ $ trigger
227+ );
228+ }
229+ }
230+ break ;
195231
196232 case Trigger::EVENT_DELETE :
197- return sprintf (
198- "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s); " ,
199- $ this ->connection ->quoteIdentifier ($ this ->resource ->getTableName ($ changelog ->getName ())),
200- $ this ->connection ->quoteIdentifier ($ changelog ->getColumnName ()),
201- $ this ->connection ->quoteIdentifier ($ this ->getColumnName ())
202- );
233+ $ trigger = 'INSERT IGNORE INTO %s (%s) VALUES (OLD.%s); ' ;
234+ break ;
203235
204236 default :
205237 return '' ;
206238 }
239+
240+ return sprintf (
241+ $ trigger ,
242+ $ this ->connection ->quoteIdentifier ($ this ->resource ->getTableName ($ changelog ->getName ())),
243+ $ this ->connection ->quoteIdentifier ($ changelog ->getColumnName ()),
244+ $ this ->connection ->quoteIdentifier ($ this ->getColumnName ())
245+ );
207246 }
208247
209248 /**
@@ -225,7 +264,7 @@ private function getAfterEventTriggerName($event)
225264 /**
226265 * Retrieve View related to subscription
227266 *
228- * @return \Magento\Framework\Mview\ ViewInterface
267+ * @return ViewInterface
229268 * @codeCoverageIgnore
230269 */
231270 public function getView ()
0 commit comments