Completed
Push — master ( 431c04...a99100 )
by Guillaume
04:35 queued 01:57
created

JsonDatabaseFactory::resolve()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 57
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 57
rs 8.7377
c 0
b 0
f 0
cc 6
nc 8
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\TablenameHasNotDefinedException;
6
use Starkerxp\DatabaseChecker\LoggerTrait;
7
use Starkerxp\DatabaseChecker\Structure\MysqlDatabase;
8
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseColumn;
9
use Starkerxp\DatabaseChecker\Structure\MysqlDatabaseTable;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
12
/**
13
 * Convert json data to array object.
14
 *
15
 * @package Starkerxp\DatabaseChecker\Factory
16
 */
17
class JsonDatabaseFactory
18
{
19
20
    use LoggerTrait;
21
    /**
22
     * @var string
23
     */
24
    private $json;
25
26
    /**
27
     * JsonDatabaseFactory constructor.
28
     *
29
     * @param string $json
30
     */
31
    public function __construct($json)
32
    {
33
        $this->json = $json;
34
    }
35
36
    /**
37
     * @return MysqlDatabase
38
     *
39
     * @throws \RuntimeException
40
     * @throws TablenameHasNotDefinedException
41
     */
42
    public function generate($databaseName): MysqlDatabase
43
    {
44
        $tables = [];
45
        try {
46
            $dataTables = $this->resolve();
47
        } catch (\Exception $e) {
48
            $this->error('An unexpected error are throw when you check json syntax');
49
50
            return [];
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
        $mysqlDatabase = new MysqlDatabase($databaseName);
82
        foreach($tables as $table){
83
            $mysqlDatabase->addTable($table);
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
        if(empty($data['tables'])){
140
            return [];
141
        }
142
143
        foreach ($data as $nomTable => $table) {
144
            $dataTable = $resolverTable->resolve($table);
145
            foreach ((array)$dataTable['columns'] as $columnName => $column) {
146
                $dataTable['columns'][$columnName] = $resolverColumns->resolve($column);
147
            }
148
            foreach (['indexes', 'uniques'] as $indexKey) {
149
                foreach ((array)$dataTable[$indexKey] as $keyIndex => $index) {
150
                    $dataTable[$indexKey][$keyIndex] = $resolverIndex->resolve($index);
151
                }
152
            }
153
            $export[$nomTable] = $dataTable;
154
        }
155
156
        return $export;
157
    }
158
159
    private function generateJsonData()
160
    {
161
        if (empty($this->json)) {
162
            return [];
163
        }
164
        if (!$data = json_decode($this->json, true)) {
165
            $data = [];
166
        }
167
168
        return $data;
169
    }
170
}
171