Passed
Push — master ( 91f02d...65071d )
by Melech
21:33 queued 07:21
created

ServiceProvider::createPdo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Orm\Provider;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use PDO;
18
use Valkyrja\Application\Env;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Application\Env was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Valkyrja\Container\Contract\Container;
20
use Valkyrja\Container\Support\Provider;
21
use Valkyrja\Orm\Contract\Manager;
22
use Valkyrja\Orm\Entity\Contract\Entity;
23
use Valkyrja\Orm\InMemoryManager;
24
use Valkyrja\Orm\MysqlManager;
25
use Valkyrja\Orm\NullManager;
26
use Valkyrja\Orm\PgsqlManager;
27
use Valkyrja\Orm\Repository\Repository;
28
use Valkyrja\Orm\SqliteManager;
29
30
/**
31
 * Class ServiceProvider.
32
 *
33
 * @author Melech Mizrachi
34
 */
35
final class ServiceProvider extends Provider
36
{
37
    /**
38
     * @inheritDoc
39
     */
40
    #[Override]
41
    public static function publishers(): array
42
    {
43
        return [
44
            Manager::class         => [self::class, 'publishManager'],
45
            MysqlManager::class    => [self::class, 'publishMysqlManager'],
46
            PgsqlManager::class    => [self::class, 'publishPgsqlManager'],
47
            SqliteManager::class   => [self::class, 'publishSqliteManager'],
48
            PDO::class             => [self::class, 'publishPdo'],
49
            InMemoryManager::class => [self::class, 'publishInMemoryManager'],
50
            NullManager::class     => [self::class, 'publishNullManager'],
51
            Repository::class      => [self::class, 'publishRepository'],
52
        ];
53
    }
54
55
    /**
56
     * @inheritDoc
57
     */
58
    #[Override]
59
    public static function provides(): array
60
    {
61
        return [
62
            Manager::class,
63
            MysqlManager::class,
64
            PgsqlManager::class,
65
            SqliteManager::class,
66
            PDO::class,
67
            InMemoryManager::class,
68
            NullManager::class,
69
            Repository::class,
70
        ];
71
    }
72
73
    /**
74
     * Publish the manager service.
75
     */
76
    public static function publishManager(Container $container): void
77
    {
78
        $env = $container->getSingleton(Env::class);
79
        /** @var class-string<Manager> $default */
80
        $default = $env::ORM_DEFAULT_MANAGER;
81
82
        $container->setSingleton(
83
            Manager::class,
84
            $container->getSingleton($default),
85
        );
86
    }
87
88
    /**
89
     * Publish the mysql manager service.
90
     */
91
    public static function publishMysqlManager(Container $container): void
92
    {
93
        $env = $container->getSingleton(Env::class);
94
        /** @var non-empty-string $db */
95
        $db = $env::ORM_MYSQL_DB;
96
        /** @var non-empty-string $host */
97
        $host = $env::ORM_MYSQL_HOST;
98
        /** @var positive-int $port */
99
        $port = $env::ORM_MYSQL_PORT;
100
        /** @var non-empty-string $user */
101
        $user = $env::ORM_MYSQL_USER;
102
        /** @var non-empty-string $password */
103
        $password = $env::ORM_MYSQL_PASSWORD;
104
        /** @var non-empty-string $charset */
105
        $charset = $env::ORM_MYSQL_CHARSET;
106
        /** @var non-empty-string|null $strict */
107
        $strict = $env::ORM_MYSQL_STRICT;
108
        /** @var non-empty-string|null $engine */
109
        $engine = $env::ORM_MYSQL_ENGINE;
110
        /** @var array<int, int|bool>|null $options */
111
        $options = $env::ORM_MYSQL_OPTIONS;
112
113
        $options ??= [
114
            PDO::ATTR_CASE              => PDO::CASE_NATURAL,
115
            PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
116
            PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
117
            PDO::ATTR_STRINGIFY_FETCHES => false,
118
            PDO::ATTR_EMULATE_PREPARES  => false,
119
        ];
120
121
        $dsn = 'mysql'
122
            . ":dbname=$db}"
123
            . ";host=$host"
124
            . ";port=$port"
125
            . ";user=$user"
126
            . ";password=$password"
127
            . ";charset=$charset"
128
            . ($strict !== null ? ";strict=$strict" : '')
129
            . ($engine !== null ? ";engine=$engine" : '');
130
131
        $container->setSingleton(
132
            MysqlManager::class,
133
            new MysqlManager(
134
                pdo: $container->getCallable(PDO::class, [$dsn, $options]),
135
                container: $container
136
            )
137
        );
138
    }
139
140
    /**
141
     * Publish the pgsql manager service.
142
     */
143
    public static function publishPgsqlManager(Container $container): void
144
    {
145
        $env = $container->getSingleton(Env::class);
146
        /** @var non-empty-string $db */
147
        $db = $env::ORM_PGSQL_DB;
148
        /** @var non-empty-string $host */
149
        $host = $env::ORM_PGSQL_HOST;
150
        /** @var positive-int $port */
151
        $port = $env::ORM_PGSQL_PORT;
152
        /** @var non-empty-string $user */
153
        $user = $env::ORM_PGSQL_USER;
154
        /** @var non-empty-string $password */
155
        $password = $env::ORM_PGSQL_PASSWORD;
156
        /** @var non-empty-string $charset */
157
        $charset = $env::ORM_PGSQL_CHARSET;
158
        /** @var non-empty-string $schema */
159
        $schema = $env::ORM_PGSQL_SCHEMA;
160
        /** @var non-empty-string $sslmode */
161
        $sslmode = $env::ORM_PGSQL_SSL_MODE;
162
        /** @var array<int, int|bool>|null $options */
163
        $options = $env::ORM_PGSQL_OPTIONS;
164
165
        $options ??= [
166
            PDO::ATTR_PERSISTENT        => true,
167
            PDO::ATTR_CASE              => PDO::CASE_NATURAL,
168
            PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
169
            PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
170
            PDO::ATTR_STRINGIFY_FETCHES => false,
171
        ];
172
173
        $dsn = 'pgsql'
174
            . ":dbname=$db}"
175
            . ";host=$host"
176
            . ";port=$port"
177
            . ";user=$user"
178
            . ";password=$password"
179
            . ";sslmode=$sslmode"
180
            . ";options='--client_encoding=$charset";
181
182
        $container->setSingleton(
183
            PgsqlManager::class,
184
            new PgsqlManager(
185
                pdo: $pdo = $container->getCallable(PDO::class, [$dsn, $options]),
186
                container: $container
187
            )
188
        );
189
190
        $pdo->query("set search_path to $schema");
191
    }
192
193
    /**
194
     * Publish the sqlite manager service.
195
     */
196
    public static function publishSqliteManager(Container $container): void
197
    {
198
        $env = $container->getSingleton(Env::class);
199
        /** @var non-empty-string $db */
200
        $db = $env::ORM_SQLITE_DB;
201
        /** @var non-empty-string $host */
202
        $host = $env::ORM_SQLITE_HOST;
203
        /** @var positive-int $port */
204
        $port = $env::ORM_SQLITE_PORT;
205
        /** @var non-empty-string $user */
206
        $user = $env::ORM_SQLITE_USER;
207
        /** @var non-empty-string $password */
208
        $password = $env::ORM_SQLITE_PASSWORD;
209
        /** @var non-empty-string $charset */
210
        $charset = $env::ORM_SQLITE_CHARSET;
211
        /** @var array<int, int|bool>|null $options */
212
        $options = $env::ORM_SQLITE_OPTIONS;
213
214
        $options ??= [
215
            PDO::ATTR_CASE              => PDO::CASE_NATURAL,
216
            PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,
217
            PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,
218
            PDO::ATTR_STRINGIFY_FETCHES => false,
219
            PDO::ATTR_EMULATE_PREPARES  => false,
220
        ];
221
222
        $dsn = 'sqlite'
223
            . ":dbname=$db}"
224
            . ";host=$host"
225
            . ";port=$port"
226
            . ";user=$user"
227
            . ";charset=$charset"
228
            . ";password=$password";
229
230
        $container->setSingleton(
231
            SqliteManager::class,
232
            new SqliteManager(
233
                pdo: $container->getCallable(PDO::class, [$dsn, $options]),
234
                container: $container
235
            )
236
        );
237
    }
238
239
    /**
240
     * Publish the PDO service.
241
     */
242
    public static function publishPdo(Container $container): void
243
    {
244
        $container->setCallable(
245
            PDO::class,
246
            [self::class, 'createPdo'],
247
        );
248
    }
249
250
    /**
251
     * Create a PDO.
252
     *
253
     * @param non-empty-string     $dsn     The dsn
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
254
     * @param array<int, int|bool> $options The options
255
     */
256
    public static function createPdo(Container $container, string $dsn, array $options): PDO
257
    {
258
        return new PDO(
259
            dsn: $dsn,
260
            options: $options
261
        );
262
    }
263
264
    /**
265
     * Publish the in memory manager service.
266
     */
267
    public static function publishInMemoryManager(Container $container): void
268
    {
269
        $container->setSingleton(
270
            InMemoryManager::class,
271
            new InMemoryManager()
272
        );
273
    }
274
275
    /**
276
     * Publish the null manager service.
277
     */
278
    public static function publishNullManager(Container $container): void
279
    {
280
        $container->setSingleton(
281
            NullManager::class,
282
            new NullManager()
283
        );
284
    }
285
286
    /**
287
     * Publish the repository service.
288
     */
289
    public static function publishRepository(Container $container): void
290
    {
291
        $container->setCallable(
292
            Repository::class,
293
            [self::class, 'createRepository'],
294
        );
295
    }
296
297
    /**
298
     * Create a repository service.
299
     *
300
     * @param class-string<Entity> $entity The entity
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Entity> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Entity>.
Loading history...
301
     */
302
    public static function createRepository(Container $container, Manager $manager, string $entity): Repository
303
    {
304
        return new Repository(
305
            manager: $manager,
306
            entity: $entity
307
        );
308
    }
309
}
310