Passed
Push — main ( b94a81...f6c2a3 )
by Pranjal
02:29
created

Database::createRecords()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 11
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A Database::tableExists() 0 5 1
1
<?php
2
/*
3
 * This file is part of the Scrawler package.
4
 *
5
 * (c) Pranjal Pandey <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Scrawler\Arca;
14
15
use Doctrine\DBAL\Connection;
16
use Doctrine\DBAL\Types\Type;
17
use Dunglas\DoctrineJsonOdm\Serializer;
18
use Dunglas\DoctrineJsonOdm\Type\JsonDocumentType;
19
use Scrawler\Arca\Manager\ModelManager;
20
use Scrawler\Arca\Manager\RecordManager;
21
use Scrawler\Arca\Manager\TableManager;
22
use Scrawler\Arca\Manager\WriteManager;
23
use Symfony\Component\Serializer\Encoder\JsonEncoder;
24
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
25
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
26
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
27
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
28
use Symfony\Component\Serializer\Normalizer\UidNormalizer;
29
30
/**
31
 * Class that manages all interaction with database.
32
 */
33
final class Database
34
{
35
    /**
36
     * Create a new Database instance.
37
     */
38
    public function __construct(
39
        private Connection $connection,
40
        private TableManager $tableManager,
41
        private RecordManager $recordManager,
42
        private WriteManager $writeManager,
43
        private ModelManager $modelManager,
44
        private Config $config,
45
    ) {
46
        $this->registerJsonDocumentType();
47
    }
48
49
    /**
50
     * Executes an SQL query and returns the number of row affected.
51
     *
52
     * @param array<mixed> $params
53
     *
54
     * @return int|numeric-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment int|numeric-string at position 2 could not be parsed: Unknown type name 'numeric-string' at position 2 in int|numeric-string.
Loading history...
55
     */
56
    public function exec(string $sql, array $params = []): int|string
57
    {
58
        return $this->connection->executeStatement($sql, $params);
59
    }
60
61
    /**
62
     * Returns array of data from SQL select statement.
63
     *
64
     * @param array<mixed> $params
65
     *
66
     * @return array<int,array<string,mixed>>
67
     */
68
    public function getAll(string $sql, array $params = []): array
69
    {
70
        return $this->connection->executeQuery($sql, $params)->fetchAllAssociative();
71
    }
72
73
    /**
74
     * Creates model from name.
75
     */
76
    public function create(string $name): Model
77
    {
78
        return $this->modelManager->create($name);
79
    }
80
81
    /**
82
     * Save record to database.
83
     */
84
    public function save(Model $model): mixed
85
    {
86
        return $this->writeManager->save($model);
87
    }
88
89
    /**
90
     * Delete record from database.
91
     */
92
    public function delete(Model $model): mixed
93
    {
94
        return $this->recordManager->delete($model);
95
    }
96
97
    /**
98
     * Get collection of all records from table.
99
     */
100
    public function get(string $table): Collection
101
    {
102
        return $this->recordManager->getAll($table);
103
    }
104
105
    /**
106
     * Get single record.
107
     */
108
    public function getOne(string $table, mixed $id): ?Model
109
    {
110
        return $this->recordManager->getById($table, $id);
111
    }
112
113
    /**
114
     * Returns QueryBuilder to build query for finding data
115
     * Eg: db()->find('user')->where('active = 1')->get();.
116
     */
117
    public function find(string $name): QueryBuilder
118
    {
119
        return $this->recordManager->find($name);
120
    }
121
122
    /**
123
     * Freezes table for production.
124
     */
125
    public function freeze(): void
126
    {
127
        $this->config->setFrozen(true);
128
    }
129
130
    /**
131
     * Helper function to unfreeze table.
132
     */
133
    public function unfreeze(): void
134
    {
135
        $this->config->setFrozen(false);
136
    }
137
138
    /**
139
     * Checks if database is currently using uuid rather than id.
140
     */
141
    public function isUsingUUID(): bool
142
    {
143
        return $this->config->isUsingUUID();
144
    }
145
146
    /**
147
     * Returns the current connection.
148
     */
149
    public function getConnection(): Connection
150
    {
151
        return $this->connection;
152
    }
153
154
    /**
155
     * Check if tables exist.
156
     *
157
     * @param array<int,string> $tables
158
     */
159
    public function tablesExist(array $tables): bool
160
    {
161
        return $this->connection
162
            ->createSchemaManager()
163
            ->tablesExist($tables);
164
    }
165
166
    /**
167
     * Check if table exists.
168
     */
169
    public function tableExists(string $table): bool
170
    {
171
        return $this->connection
172
            ->createSchemaManager()
173
            ->tableExists($table);
174
    }
175
176
    /**
177
     * Register additional json_document type.
178
     */
179
    private function registerJsonDocumentType(): void
180
    {
181
        if (!Type::hasType('json_document')) {
182
            Type::addType('json_document', JsonDocumentType::class);
183
            // @phpstan-ignore-next-line
184
            Type::getType('json_document')->setSerializer(
0 ignored issues
show
Bug introduced by
The method setSerializer() does not exist on Doctrine\DBAL\Types\Type. It seems like you code against a sub-type of Doctrine\DBAL\Types\Type such as Dunglas\DoctrineJsonOdm\Type\JsonDocumentType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

184
            Type::getType('json_document')->/** @scrutinizer ignore-call */ setSerializer(
Loading history...
185
                new Serializer([new BackedEnumNormalizer(), new UidNormalizer(), new DateTimeNormalizer(), new ArrayDenormalizer(), new ObjectNormalizer()], [new JsonEncoder()])
186
            );
187
        }
188
    }
189
}
190