Completed
Push — master ( 3a9351...acf721 )
by Neomerx
06:52
created

SeedTrait::getModelSchemas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php namespace Limoncello\Data\Seeds;
2
3
/**
4
 * Copyright 2015-2017 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Closure;
20
use DateTimeImmutable;
21
use Doctrine\DBAL\Connection;
22
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
23
use Doctrine\DBAL\Schema\AbstractSchemaManager;
24
use Limoncello\Contracts\Data\ModelSchemaInfoInterface;
25
use Limoncello\Contracts\Data\SeedInterface;
26
use PDO;
27
use Psr\Container\ContainerInterface;
28
29
/**
30
 * @package Limoncello\Data
31
 */
32
trait SeedTrait
33
{
34
    /**
35
     * @var ContainerInterface
36
     */
37
    private $container;
38
39
    /**
40
     * @inheritdoc
41
     */
42 1
    public function init(ContainerInterface $container): SeedInterface
43
    {
44 1
        $this->container = $container;
45
46
        /** @var SeedInterface $self */
47 1
        $self = $this;
48
49 1
        return $self;
50
    }
51
52
    /**
53
     * @return ContainerInterface
54
     */
55 1
    protected function getContainer(): ContainerInterface
56
    {
57 1
        return $this->container;
58
    }
59
60
    /**
61
     * @return Connection
62
     */
63 1
    protected function getConnection(): Connection
64
    {
65 1
        assert($this->getContainer()->has(Connection::class) === true);
66
67 1
        return $this->getContainer()->get(Connection::class);
68
    }
69
70
    /**
71
     * @return ModelSchemaInfoInterface
72
     */
73 1
    protected function getModelSchemas(): ModelSchemaInfoInterface
74
    {
75 1
        assert($this->getContainer()->has(ModelSchemaInfoInterface::class) === true);
76
77 1
        return $this->getContainer()->get(ModelSchemaInfoInterface::class);
78
    }
79
80
    /**
81
     * @return AbstractSchemaManager
82
     */
83 1
    protected function getSchemaManager(): AbstractSchemaManager
84
    {
85 1
        return $this->getConnection()->getSchemaManager();
86
    }
87
88
    /**
89
     * @return string
90
     */
91 1
    protected function now(): string
92
    {
93 1
        $format = $this->getSchemaManager()->getDatabasePlatform()->getDateTimeFormatString();
94 1
        $now    = (new DateTimeImmutable())->format($format);
95
96 1
        return $now;
97
    }
98
99
    /**
100
     * @param string   $tableName
101
     * @param null|int $limit
102
     *
103
     * @return array
104
     */
105 1
    protected function readTableData(string $tableName, int $limit = null): array
106
    {
107 1
        assert($limit === null || $limit > 0);
108
109 1
        $builder = $this->getConnection()->createQueryBuilder();
110
        $builder
111 1
            ->select('*')
112 1
            ->from($tableName);
113
114 1
        $limit === null ?: $builder->setMaxResults($limit);
115
116 1
        $result = $builder->execute()->fetchAll(PDO::FETCH_ASSOC);
117
118 1
        return $result;
119
    }
120
121
    /**
122
     * @param string   $modelClass
123
     * @param null|int $limit
124
     *
125
     * @return array
126
     */
127 1
    protected function readModelsData(string $modelClass, int $limit = null): array
128
    {
129 1
        return $this->readTableData($this->getModelSchemas()->getTable($modelClass), $limit);
130
    }
131
132
    /**
133
     * @param int     $records
134
     * @param string  $tableName
135
     * @param Closure $dataClosure
136
     *
137
     * @return void
138
     */
139 1
    protected function seedTableData(int $records, $tableName, Closure $dataClosure): void
140
    {
141 1
        $connection = $this->getConnection();
142 1
        for ($i = 0; $i !== $records; $i++) {
143 1
            $this->insertRow($tableName, $connection, $dataClosure($this->getContainer()));
144
        }
145
    }
146
147
    /**
148
     * @param int     $records
149
     * @param string  $modelClass
150
     * @param Closure $dataClosure
151
     *
152
     * @return void
153
     */
154 1
    protected function seedModelsData(int $records, string $modelClass, Closure $dataClosure): void
155
    {
156 1
        $this->seedTableData($records, $this->getModelSchemas()->getTable($modelClass), $dataClosure);
157
    }
158
159
    /**
160
     * @param string $tableName
161
     * @param array  $data
162
     *
163
     * @return string|null
164
     */
165 1
    protected function seedRowData(string $tableName, array $data): ?string
166
    {
167 1
        return $this->insertRow($tableName, $this->getConnection(), $data);
168
    }
169
170
    /**
171
     * @param string $modelClass
172
     * @param array  $data
173
     *
174
     * @return string|null
175
     */
176 1
    protected function seedModelData(string $modelClass, array $data): ?string
177
    {
178 1
        return $this->seedRowData($this->getModelSchemas()->getTable($modelClass), $data);
179
    }
180
181
    /**
182
     * @return string
183
     */
184 1
    protected function getLastInsertId(): string
185
    {
186 1
        return $this->getConnection()->lastInsertId();
187
    }
188
189
    /**
190
     * @param string     $tableName
191
     * @param Connection $connection
192
     * @param array      $data
193
     *
194
     * @return string|null
195
     */
196 1
    private function insertRow($tableName, Connection $connection, array $data): ?string
197
    {
198 1
        $quotedFields = [];
199 1
        foreach ($data as $column => $value) {
200 1
            $quotedFields["`$column`"] = $value;
201
        }
202
203 1
        $index = null;
204
        try {
205 1
            $result = $connection->insert($tableName, $quotedFields);
206 1
            assert($result !== false, 'Insert failed');
207 1
            $index  = $connection->lastInsertId();
208 1
        } catch (UniqueConstraintViolationException $e) {
209
            // ignore non-unique records
210
        }
211
212 1
        return $index;
213
    }
214
}
215