Completed
Push — master ( adc131...6e9eb4 )
by Kevin
03:32
created

PrimaryKeyRegistry::addValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
namespace DBFaker\Helpers;
3
4
5
use DBFaker\Exceptions\PrimaryKeyColumnMismatchException;
6
use DBFaker\Exceptions\SchemaLogicException;
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\Schema\Column;
9
use Doctrine\DBAL\Schema\Table;
10
11
class PrimaryKeyRegistry
12
{
13
14
    /**
15
     * @var string
16
     */
17
    private $tableName;
18
19
    /**
20
     * @var string[]
21
     */
22
    private $columnNames;
23
24
    /**
25
     * @var Connection
26
     */
27
    private $connection;
28
29
    /**
30
     * @var array
31
     */
32
    private $values;
33
34
    /**
35
     * @var bool
36
     */
37
    private $valuesLoaded = false;
38
39
    /**
40
     * PrimaryKeyRegistry constructor.
41
     * @param Connection $connection
42
     * @param Table $table
43
     * @param SchemaHelper $helper
44
     * @param bool $isSelfReferencing
45
     * @throws \Doctrine\DBAL\DBALException
46
     */
47
    public function __construct(Connection $connection, Table $table, SchemaHelper $helper, $isSelfReferencing = false)
48
    {
49
        $this->connection = $connection;
50
        $refTable = null;
51
        $refCols = [];
52
        foreach ($table->getForeignKeys() as $fk){
53
            if ($helper->isExtendingKey($fk) && $table->getName() !== $fk->getForeignTableName()){
54
                $refTable = $fk->getForeignTableName();
55
                $refCols = $fk->getForeignColumns();
56
            }
57
        }
58
        if ($isSelfReferencing || !$refTable){
59
            $pk = $table->getPrimaryKey();
60
            if ($pk === null){
61
                throw new SchemaLogicException('No PK on table ' . $table->getName());
62
            }
63
            $refTable = $table->getName();
64
            $refCols = $pk->getColumns();
65
        }
66
        $this->tableName = $refTable;
67
        $this->columnNames = $refCols;
68
        sort($this->columnNames);
69
    }
70
71
    /**
72
     * Loads all PK values fro ma table and stores them
73
     * @throws \Doctrine\DBAL\DBALException
74
     */
75
    public function loadValuesFromTable() : PrimaryKeyRegistry
76
    {
77
        if (!$this->valuesLoaded){
78
            $this->values = [];
79
            $colNames = implode(",", $this->columnNames);
80
            $rows = $this->connection->query("SELECT $colNames FROM " . $this->tableName)->fetchAll();
81
            foreach ($rows as $row){
82
                $pk = [];
83
                foreach ($this->columnNames as $column){
84
                    $pk[$column] = $row[$column];
85
                }
86
                $this->values[] = $pk;
87
            }
88
        }
89
        return $this;
90
    }
91
92
    /**
93
     * Adds a PK value to the store
94
     * @param mixed[] $value
95
     * @throws \DBFaker\Exceptions\PrimaryKeyColumnMismatchException
96
     */
97
    public function addValue(array $value) : void
98
    {
99
        $keys = array_keys($value);
100
        sort($keys);
101
        if ($this->columnNames != $keys){
102
            throw new PrimaryKeyColumnMismatchException('PrimaryKeys do not match between PKStore and addValue');
103
        }
104
        $this->values[] = $value;
105
    }
106
107
    /**
108
     * @param $excludedValues
109
     * @return mixed[]
110
     * @throws \Exception
111
     */
112
    public function getRandomValue($excludedValues) : array
113
    {
114
        $values = array_filter($this->values, function($value) use ($excludedValues){
115
            return !\in_array($value, $excludedValues, true);
116
        });
117
        return $values[array_rand($values, 1)];
118
    }
119
120
    /**
121
     * @return mixed[][]
122
     */
123
    public function getAllValues() : array
124
    {
125
        return $this->values;
126
    }
127
128
}