10
10
11
11
use Magento \Framework \App \ResourceConnection ;
12
12
use Magento \Framework \DB \Ddl \Trigger ;
13
+ use Magento \Framework \DB \Ddl \TriggerFactory ;
14
+ use Magento \Framework \Mview \ViewInterface ;
13
15
14
16
class Subscription implements SubscriptionInterface
15
17
{
@@ -21,12 +23,12 @@ class Subscription implements SubscriptionInterface
21
23
protected $ connection ;
22
24
23
25
/**
24
- * @var \Magento\Framework\DB\Ddl\ TriggerFactory
26
+ * @var TriggerFactory
25
27
*/
26
28
protected $ triggerFactory ;
27
29
28
30
/**
29
- * @var \Magento\Framework\Mview\View\ CollectionInterface
31
+ * @var CollectionInterface
30
32
*/
31
33
protected $ viewCollection ;
32
34
@@ -57,21 +59,32 @@ class Subscription implements SubscriptionInterface
57
59
*/
58
60
protected $ resource ;
59
61
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
+
60
70
/**
61
71
* @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
65
75
* @param string $tableName
66
76
* @param string $columnName
77
+ * @param array $ignoredUpdateColumns
78
+ * @throws \DomainException
67
79
*/
68
80
public function __construct (
69
81
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 ,
73
85
$ tableName ,
74
- $ columnName
86
+ $ columnName ,
87
+ array $ ignoredUpdateColumns = []
75
88
) {
76
89
$ this ->connection = $ resource ->getConnection ();
77
90
$ this ->triggerFactory = $ triggerFactory ;
@@ -80,12 +93,14 @@ public function __construct(
80
93
$ this ->tableName = $ tableName ;
81
94
$ this ->columnName = $ columnName ;
82
95
$ this ->resource = $ resource ;
96
+ $ this ->ignoredUpdateColumns = $ ignoredUpdateColumns ;
83
97
}
84
98
85
99
/**
86
- * Create subsciption
100
+ * Create subscription
87
101
*
88
- * @return \Magento\Framework\Mview\View\SubscriptionInterface
102
+ * @return SubscriptionInterface
103
+ * @throws \InvalidArgumentException
89
104
*/
90
105
public function create ()
91
106
{
@@ -102,7 +117,7 @@ public function create()
102
117
103
118
// Add statements for linked views
104
119
foreach ($ this ->getLinkedViews () as $ view ) {
105
- /** @var \Magento\Framework\Mview\ ViewInterface $view */
120
+ /** @var ViewInterface $view */
106
121
$ trigger ->addStatement ($ this ->buildStatement ($ event , $ view ->getChangelog ()));
107
122
}
108
123
@@ -116,7 +131,8 @@ public function create()
116
131
/**
117
132
* Remove subscription
118
133
*
119
- * @return \Magento\Framework\Mview\View\SubscriptionInterface
134
+ * @return SubscriptionInterface
135
+ * @throws \InvalidArgumentException
120
136
*/
121
137
public function remove ()
122
138
{
@@ -131,7 +147,7 @@ public function remove()
131
147
132
148
// Add statements for linked views
133
149
foreach ($ this ->getLinkedViews () as $ view ) {
134
- /** @var \Magento\Framework\Mview\ ViewInterface $view */
150
+ /** @var ViewInterface $view */
135
151
$ trigger ->addStatement ($ this ->buildStatement ($ event , $ view ->getChangelog ()));
136
152
}
137
153
@@ -154,10 +170,10 @@ public function remove()
154
170
protected function getLinkedViews ()
155
171
{
156
172
if (!$ this ->linkedViews ) {
157
- $ viewList = $ this ->viewCollection ->getViewsByStateMode (\ Magento \ Framework \ Mview \ View \ StateInterface::MODE_ENABLED );
173
+ $ viewList = $ this ->viewCollection ->getViewsByStateMode (StateInterface::MODE_ENABLED );
158
174
159
175
foreach ($ viewList as $ view ) {
160
- /** @var \Magento\Framework\Mview\ ViewInterface $view */
176
+ /** @var ViewInterface $view */
161
177
// Skip the current view
162
178
if ($ view ->getId () == $ this ->getView ()->getId ()) {
163
179
continue ;
@@ -175,35 +191,58 @@ protected function getLinkedViews()
175
191
}
176
192
177
193
/**
178
- * Build trigger statement for INSER , UPDATE, DELETE events
194
+ * Build trigger statement for INSERT , UPDATE, DELETE events
179
195
*
180
196
* @param string $event
181
- * @param \Magento\Framework\Mview\View\ ChangelogInterface $changelog
197
+ * @param ChangelogInterface $changelog
182
198
* @return string
183
199
*/
184
200
protected function buildStatement ($ event , $ changelog )
185
201
{
186
202
switch ($ event ) {
187
203
case Trigger::EVENT_INSERT :
204
+ $ trigger = 'INSERT IGNORE INTO %s (%s) VALUES (NEW.%s); ' ;
205
+ break ;
206
+
188
207
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 ;
195
231
196
232
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 ;
203
235
204
236
default :
205
237
return '' ;
206
238
}
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
+ );
207
246
}
208
247
209
248
/**
@@ -225,7 +264,7 @@ private function getAfterEventTriggerName($event)
225
264
/**
226
265
* Retrieve View related to subscription
227
266
*
228
- * @return \Magento\Framework\Mview\ ViewInterface
267
+ * @return ViewInterface
229
268
* @codeCoverageIgnore
230
269
*/
231
270
public function getView ()
0 commit comments