TDBMSchemaAnalyzer   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 8
dl 0
loc 137
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getCachePrefix() 0 8 2
A getSchema() 0 14 3
B getPivotTableLinkedToTable() 0 24 5
C getIncomingForeignKeys() 0 27 8
1
<?php
2
3
namespace Mouf\Database\TDBM;
4
5
use Doctrine\Common\Cache\Cache;
6
use Doctrine\DBAL\Connection;
7
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
8
use Doctrine\DBAL\Schema\Schema;
9
use Doctrine\DBAL\Schema\Table;
10
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
11
12
/**
13
 * This class is used to analyze the schema and return valuable information / hints.
14
 */
15
class TDBMSchemaAnalyzer
16
{
17
    private $connection;
18
19
    /**
20
     * @var Schema
21
     */
22
    private $schema;
23
24
    /**
25
     * @var string
26
     */
27
    private $cachePrefix;
28
29
    /**
30
     * @var Cache
31
     */
32
    private $cache;
33
34
    /**
35
     * @var SchemaAnalyzer
36
     */
37
    private $schemaAnalyzer;
38
39
    /**
40
     * @param Connection     $connection     The DBAL DB connection to use
41
     * @param Cache          $cache          A cache service to be used
42
     * @param SchemaAnalyzer $schemaAnalyzer The schema analyzer that will be used to find shortest paths...
43
     *                                       Will be automatically created if not passed
44
     */
45
    public function __construct(Connection $connection, Cache $cache, SchemaAnalyzer $schemaAnalyzer)
46
    {
47
        $this->connection = $connection;
48
        $this->cache = $cache;
49
        $this->schemaAnalyzer = $schemaAnalyzer;
50
    }
51
52
    /**
53
     * Returns a unique ID for the current connection. Useful for namespacing cache entries in the current connection.
54
     *
55
     * @return string
56
     */
57
    public function getCachePrefix()
58
    {
59
        if ($this->cachePrefix === null) {
60
            $this->cachePrefix = hash('md4', $this->connection->getHost().'-'.$this->connection->getPort().'-'.$this->connection->getDatabase().'-'.$this->connection->getDriver()->getName());
61
        }
62
63
        return $this->cachePrefix;
64
    }
65
66
    /**
67
     * Returns the (cached) schema.
68
     *
69
     * @return Schema
70
     */
71
    public function getSchema()
72
    {
73
        if ($this->schema === null) {
74
            $cacheKey = $this->getCachePrefix().'_schema';
75
            if ($this->cache->contains($cacheKey)) {
76
                $this->schema = $this->cache->fetch($cacheKey);
77
            } else {
78
                $this->schema = $this->connection->getSchemaManager()->createSchema();
79
                $this->cache->save($cacheKey, $this->schema);
80
            }
81
        }
82
83
        return $this->schema;
84
    }
85
86
    /**
87
     * Returns the list of pivot tables linked to table $tableName.
88
     *
89
     * @param string $tableName
90
     *
91
     * @return array|string[]
92
     */
93
    public function getPivotTableLinkedToTable($tableName)
94
    {
95
        $cacheKey = $this->getCachePrefix().'_pivottables_link_'.$tableName;
96
        if ($this->cache->contains($cacheKey)) {
97
            return $this->cache->fetch($cacheKey);
98
        }
99
100
        $pivotTables = [];
101
102
        $junctionTables = $this->schemaAnalyzer->detectJunctionTables(true);
103
        foreach ($junctionTables as $table) {
104
            $fks = $table->getForeignKeys();
105
            foreach ($fks as $fk) {
106
                if ($fk->getForeignTableName() == $tableName) {
107
                    $pivotTables[] = $table->getName();
108
                    break;
109
                }
110
            }
111
        }
112
113
        $this->cache->save($cacheKey, $pivotTables);
114
115
        return $pivotTables;
116
    }
117
118
    /**
119
     * Returns the list of foreign keys pointing to the table represented by this bean, excluding foreign keys
120
     * from junction tables and from inheritance.
121
     *
122
     * @return ForeignKeyConstraint[]
123
     */
124
    public function getIncomingForeignKeys($tableName)
125
    {
126
        $junctionTables = $this->schemaAnalyzer->detectJunctionTables(true);
127
        $junctionTableNames = array_map(function (Table $table) {
128
            return $table->getName();
129
        }, $junctionTables);
130
        $childrenRelationships = $this->schemaAnalyzer->getChildrenRelationships($tableName);
131
132
        $fks = [];
133
        foreach ($this->getSchema()->getTables() as $table) {
134
            foreach ($table->getForeignKeys() as $fk) {
135
                if ($fk->getForeignTableName() === $tableName) {
136
                    if (in_array($fk->getLocalTableName(), $junctionTableNames)) {
137
                        continue;
138
                    }
139
                    foreach ($childrenRelationships as $childFk) {
140
                        if ($fk->getLocalTableName() === $childFk->getLocalTableName() && $fk->getLocalColumns() === $childFk->getLocalColumns()) {
141
                            continue 2;
142
                        }
143
                    }
144
                    $fks[] = $fk;
145
                }
146
            }
147
        }
148
149
        return $fks;
150
    }
151
}
152