-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
Copy pathTriggerCleaner.php
127 lines (112 loc) · 3.44 KB
/
TriggerCleaner.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Framework\Mview;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Mview\View\CollectionFactory;
use Magento\Framework\Mview\View\StateInterface;
/**
* Class for removing old triggers that were created by mview
*/
class TriggerCleaner
{
/**
* @var CollectionFactory
*/
private $viewCollectionFactory;
/**
* @var ResourceConnection
*/
private $resource;
/**
* @var ViewFactory
*/
private $viewFactory;
/**
* @param CollectionFactory $viewCollectionFactory
* @param ResourceConnection $resource
* @param ViewFactory $viewFactory
*/
public function __construct(
CollectionFactory $viewCollectionFactory,
ResourceConnection $resource,
ViewFactory $viewFactory
) {
$this->viewCollectionFactory = $viewCollectionFactory;
$this->resource = $resource;
$this->viewFactory = $viewFactory;
}
/**
* Remove the outdated trigger from the system
*
* @return bool
* @throws \Exception
*/
public function removeTriggers(): bool
{
// Get list of views that are enabled
$viewCollection = $this->viewCollectionFactory->create();
$viewList = $viewCollection->getViewsByStateMode(StateInterface::MODE_ENABLED);
// Unsubscribe existing view to remove triggers from db
foreach ($viewList as $view) {
$view->unsubscribe();
}
// Remove any remaining triggers from db that are not linked to a view
$triggerTableNames = $this->getTableNamesWithTriggers();
foreach ($triggerTableNames as $tableName) {
$view = $this->createViewByTableName($tableName);
$view->unsubscribe();
$view->getState()->delete();
}
// Restore the previous state of the views to add triggers back to db
foreach ($viewList as $view) {
$view->subscribe();
}
return true;
}
/**
* Retrieve list of table names that have triggers
*
* @return array
*/
private function getTableNamesWithTriggers(): array
{
$connection = $this->resource->getConnection();
$dbName = $this->resource->getSchemaName(ResourceConnection::DEFAULT_CONNECTION);
$sql = $connection->select()
->from(
['information_schema.TRIGGERS'],
['EVENT_OBJECT_TABLE']
)
->distinct(true)
->where('TRIGGER_SCHEMA = ?', $dbName);
return $connection->fetchCol($sql);
}
/**
* Create view by db table name
*
* Create a view that has the table name so that unsubscribe can be used to
* remove triggers with the correct naming structure from the db
*
* @param string $tableName
* @return ViewInterface
*/
private function createViewByTableName(string $tableName): ViewInterface
{
$subscription[$tableName] = [
'name' => $tableName,
'column' => '',
'subscription_model' => null
];
$data['data'] = [
'subscriptions' => $subscription,
];
$view = $this->viewFactory->create($data);
$view->setId('old_view');
$view->getState()->setMode(StateInterface::MODE_ENABLED);
return $view;
}
}