Completed
Branch 1.1 (23eb45)
by David
02:38
created

LocalChangesTracker::createUpdateTrigger()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 31
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 31
rs 8.8571
cc 2
eloc 10
nc 2
nop 1
1
<?php
2
3
4
namespace Wabel\Zoho\CRM\Copy;
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Schema\Table;
7
use Psr\Log\LoggerInterface;
8
9
/**
10
 * This class is in charge of tracking local files.
11
 * To do so, it can add a set of triggers that observe and track changes in tables.
12
 */
13
class LocalChangesTracker
14
{
15
    /**
16
     * @var Connection
17
     */
18
    private $connection;
19
20
    /**
21
     * @var LoggerInterface
22
     */
23
    private $logger;
24
25
    /**
26
     * @param Connection $connection
27
     */
28
    public function __construct(Connection $connection, LoggerInterface $logger)
29
    {
30
        $this->connection = $connection;
31
        $this->logger = $logger;
32
    }
33
34
35
    public function createTrackingTables()
36
    {
37
        $schema = new \Doctrine\DBAL\Schema\Schema();
38
39
        $localUpdate = $schema->createTable("local_update");
40
        $localUpdate->addColumn("table_name", 'string', ['length' => 100]);
41
        $localUpdate->addColumn("id", 'string', ['length' => 100]);
42
        $localUpdate->addColumn("field_name", 'string', ['length' => 100]);
43
        $localUpdate->setPrimaryKey(array("table_name", "id", "field_name"));
44
45
        $localInsert = $schema->createTable("local_insert");
46
        $localInsert->addColumn("table_name", 'string', ['length' => 100]);
47
        $localInsert->addColumn("id", 'string', ['length' => 100]);
48
        $localInsert->setPrimaryKey(array("table_name", "id"));
49
50
        $localDelete = $schema->createTable("local_delete");
51
        $localDelete->addColumn("table_name", 'string', ['length' => 100]);
52
        $localDelete->addColumn("id", 'string', ['length' => 100]);
53
        $localDelete->setPrimaryKey(array("table_name", "id"));
54
55
        $dbalTableDiffService = new DbalTableDiffService($this->connection, $this->logger);
56
        $dbalTableDiffService->createOrUpdateTable($localUpdate);
57
        $dbalTableDiffService->createOrUpdateTable($localInsert);
58
        $dbalTableDiffService->createOrUpdateTable($localDelete);
59
    }
60
61 View Code Duplication
    public function createInsertTrigger(Table $table)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
    {
63
        $triggerName = sprintf("TRG_%s_ONINSERT", $table->getName());
64
65
        $sql = sprintf('
66
            DROP TRIGGER IF EXISTS %s;
67
            
68
            CREATE TRIGGER %s AFTER INSERT ON `%s` 
69
            FOR EACH ROW
70
            BEGIN
71
              IF (NEW.lastActivityTime IS NULL) THEN
72
                INSERT INTO local_insert VALUES (%s, NEW.id);
73
                DELETE FROM local_delete WHERE table_name = %s AND id = NEW.id;
74
                DELETE FROM local_update WHERE table_name = %s AND id = NEW.id;
75
              END IF;
76
            END;
77
            
78
            ', $triggerName, $triggerName, $table->getName(), $this->connection->quote($table->getName()), $this->connection->quote($table->getName()), $this->connection->quote($table->getName()));
79
80
81
        $this->connection->exec($sql);
82
    }
83
84 View Code Duplication
    public function createDeleteTrigger(Table $table)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
    {
86
        $triggerName = sprintf("TRG_%s_ONDELETE", $table->getName());
87
88
        $sql = sprintf('
89
            DROP TRIGGER IF EXISTS %s;
90
            
91
            CREATE TRIGGER %s BEFORE DELETE ON `%s` 
92
            FOR EACH ROW
93
            BEGIN
94
              INSERT INTO local_delete VALUES (%s, OLD.id);
95
              DELETE FROM local_insert WHERE table_name = %s AND id = OLD.id;
96
              DELETE FROM local_update WHERE table_name = %s AND id = OLD.id;
97
            END;
98
            
99
            ', $triggerName, $triggerName, $table->getName(), $this->connection->quote($table->getName()), $this->connection->quote($table->getName()), $this->connection->quote($table->getName()));
100
101
102
        $this->connection->exec($sql);
103
    }
104
105
    public function createUpdateTrigger(Table $table)
106
    {
107
        $triggerName = sprintf("TRG_%s_ONUPDATE", $table->getName());
108
109
        $innerCode = '';
110
111
        foreach ($table->getColumns() as $column) {
112
            $columnName = $this->connection->quoteIdentifier($column->getName());
113
            $innerCode .= sprintf('
114
                IF (NEW.%s != OLD.%s) THEN
115
                  REPLACE INTO local_update VALUES (%s, NEW.id, %s);
116
                END IF;
117
            ', $columnName, $columnName, $this->connection->quote($table->getName()), $this->connection->quote($column->getName()));
118
        }
119
120
        $sql = sprintf('
121
            DROP TRIGGER IF EXISTS %s;
122
            
123
            CREATE TRIGGER %s AFTER UPDATE ON `%s` 
124
            FOR EACH ROW
125
            BEGIN
126
              IF (NEW.lastActivityTime = OLD.lastActivityTime) THEN
127
            %s
128
              END IF;
129
            END;
130
            
131
            ', $triggerName, $triggerName, $table->getName(), $innerCode);
132
133
134
        $this->connection->exec($sql);
135
    }
136
}
137