JsonDatabaseFactory::resolve()   A
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 54
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 54
c 0
b 0
f 0
rs 9.0808
cc 5
nc 7
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Starkerxp\DatabaseChecker\Factory;
4
5
use Starkerxp\DatabaseChecker\Exception\JsonInvalidFormatException;
6
use Starkerxp\DatabaseChecker\Exception\TablenameHasNotDefinedException;
7
use Starkerxp\DatabaseChecker\LoggerTrait;
8
use Starkerxp\DatabaseChecker\Structure\MysqlDatabase;
9
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseColumn;
10
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseTable;
11
use Symfony\Component\OptionsResolver\OptionsResolver;
12
13
/**
14
 * Convert json data to array object.
15
 *
16
 * @package Starkerxp\DatabaseChecker\Factory
17
 */
18
class JsonDatabaseFactory
19
{
20
21
    use LoggerTrait;
22
    /**
23
     * @var string
24
     */
25
    private $json;
26
27
    /**
28
     * JsonDatabaseFactory constructor.
29
     *
30
     * @param string $json
31
     */
32
    public function __construct($json)
33
    {
34
        $this->json = $json;
35
    }
36
37
    /**
38
     * @return MysqlDatabase
39
     *
40
     * @throws \RuntimeException
41
     * @throws TablenameHasNotDefinedException
42
     */
43
    public function generate($databaseName): MysqlDatabase
44
    {
45
        $tables = [];
46
        $mysqlDatabase = new MysqlDatabase($databaseName);
47
        try {
48
            $dataTables = $this->resolve();
49
        } catch (\Exception $e) {
50
            throw new JsonInvalidFormatException('An unexpected error are throw when you check json syntax');
51
        }
52
        foreach ($dataTables as $tableName => $dataTable) {
53
            try {
54
                $table = new MysqlDatabaseTable($tableName);
55
            } catch (TablenameHasNotDefinedException $e) {
56
                throw $e;
57
            }
58
            if (isset($dataTable['collate'])) {
59
                $table->setCollate($dataTable['collate']);
60
            }
61
            foreach ((array) $dataTable['columns'] as $columnName => $row) {
62
                $column = new MysqlDatabaseColumn($columnName, $row['type'], $row['length'], $row['nullable'], $row['defaultValue'], $row['extra']);
63
                if (isset($row['collate']) || $table->getCollate()) {
64
                    $column->setCollate($row['collate']);
65
                }
66
                $table->addColumn($column);
67
68
            }
69
            foreach ((array) $dataTable['indexes'] as $row) {
70
                $table->addIndex($row['columns'], $row['name']);
71
            }
72
            if (isset($dataTable['primary'])) {
73
                $table->addPrimary((array) $dataTable['primary']);
74
            }
75
            foreach ((array) $dataTable['uniques'] as $row) {
76
                $table->addUnique($row['columns'], $row['name']);
77
            }
78
            $tables[] = $table;
79
        }
80
81
        foreach ($tables as $table) {
82
            $mysqlDatabase->addTable($table);
83
        }
84
85
        return $mysqlDatabase;
86
    }
87
88
    /**
89
     * Check syntax of array.
90
     *
91
     * @return array
92
     *
93
     * @throws \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
94
     * @throws \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException
95
     * @throws \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
96
     * @throws \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
97
     * @throws \Symfony\Component\OptionsResolver\Exception\AccessException
98
     * @throws \Symfony\Component\OptionsResolver\Exception\NoSuchOptionException
99
     */
100
    protected function resolve(): array
101
    {
102
        $data = $this->generateJsonData();
103
104
        // On force les valeurs par d�faut.
105
        $resolverTable = new OptionsResolver();
106
        $resolverTable->setRequired(['columns']);
107
        $resolverTable->setDefaults(
108
            [
109
                'columns' => [],
110
                'indexes' => [],
111
                'fulltexts' => [],
112
                'primary' => null,
113
                'uniques' => [],
114
                'collate' => null,
115
            ]
116
        );
117
118
        $resolverColumns = new OptionsResolver();
119
        $resolverColumns->setRequired(['type']);
120
        $resolverColumns->setDefaults(
121
            [
122
                'length' => null,
123
                'nullable' => false,
124
                'defaultValue' => null,
125
                'extra' => null,
126
                'collate' => null,
127
            ]
128
        );
129
130
        $resolverIndex = new OptionsResolver();
131
        $resolverIndex->setDefaults(
132
            [
133
                'name' => '',
134
                'columns' => [],
135
            ]
136
        );
137
        $export = [];
138
        $data = $data['tables'];
139
140
        foreach ($data as $nomTable => $table) {
141
            $dataTable = $resolverTable->resolve($table);
142
            foreach ((array) $dataTable['columns'] as $columnName => $column) {
143
                $dataTable['columns'][$columnName] = $resolverColumns->resolve($column);
144
            }
145
            foreach (['indexes', 'uniques'] as $indexKey) {
146
                foreach ((array) $dataTable[$indexKey] as $keyIndex => $index) {
147
                    $dataTable[$indexKey][$keyIndex] = $resolverIndex->resolve($index);
148
                }
149
            }
150
            $export[$nomTable] = $dataTable;
151
        }
152
153
        return $export;
154
    }
155
156
    private function generateJsonData()
157
    {
158
        if (empty($this->json)) {
159
            return [];
160
        }
161
        if (!$data = json_decode($this->json, true)) {
162
            $data = [];
163
        }
164
165
        return $data;
166
    }
167
}
168