Skip to content

Commit e5c5ced

Browse files
authored
Merge pull request #8230 from kenjis/feat-db-type-converter
feat: add DataConverter to convert types
2 parents d4362c4 + 7199ac4 commit e5c5ced

22 files changed

+1349
-95
lines changed

deptrac.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ parameters:
3535
collectors:
3636
- type: className
3737
regex: ^Codeigniter\\Database\\.*
38+
- name: DataCaster
39+
collectors:
40+
- type: className
41+
regex: ^Codeigniter\\DataCaster\\.*
42+
- name: DataConverter
43+
collectors:
44+
- type: className
45+
regex: ^Codeigniter\\DataConverter\\.*
3846
- name: Email
3947
collectors:
4048
- type: className
@@ -166,10 +174,16 @@ parameters:
166174
- Entity
167175
- Events
168176
- I18n
177+
DataCaster:
178+
- I18n
179+
- URI
180+
DataConverter:
181+
- DataCaster
169182
Email:
170183
- I18n
171184
- Events
172185
Entity:
186+
- DataCaster
173187
- I18n
174188
Files:
175189
- I18n
@@ -228,6 +242,11 @@ parameters:
228242
- CodeIgniter\HTTP\Header
229243
- CodeIgniter\HTTP\IncomingRequest
230244
- CodeIgniter\HTTP\ResponseInterface
245+
CodeIgniter\DataCaster\DataCaster:
246+
- CodeIgniter\Entity\Cast\CastInterface
247+
- CodeIgniter\Entity\Exceptions\CastException
248+
CodeIgniter\DataCaster\Exceptions\CastException:
249+
- CodeIgniter\Entity\Exceptions\CastException
231250
CodeIgniter\Entity\Cast\URICast:
232251
- CodeIgniter\HTTP\URI
233252
CodeIgniter\Log\Handlers\ChromeLoggerHandler:

phpstan-baseline.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@
13181318
];
13191319
$ignoreErrors[] = [
13201320
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
1321-
'count' => 3,
1321+
'count' => 1,
13221322
'path' => __DIR__ . '/system/Entity/Entity.php',
13231323
];
13241324
$ignoreErrors[] = [

psalm-baseline.xml

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
2+
<files psalm-version="5.20.0@3f284e96c9d9be6fe6b15c79416e1d1903dcfef4">
33
<file src="app/Config/View.php">
44
<UndefinedDocblockClass>
55
<code><![CDATA[array<string, ParserCallableString>]]></code>
@@ -26,12 +26,6 @@
2626
<code>Memcache|Memcached</code>
2727
</UndefinedDocblockClass>
2828
</file>
29-
<file src="system/Commands/Utilities/Routes/ControllerMethodReader.php">
30-
<DuplicateArrayKey>
31-
<code>$routeWithoutController</code>
32-
<code>$routeWithoutController</code>
33-
</DuplicateArrayKey>
34-
</file>
3529
<file src="system/Config/View.php">
3630
<UndefinedDocblockClass>
3731
<code><![CDATA[array<string, array<parser_callable_string>|parser_callable_string|parser_callable>]]></code>
@@ -91,15 +85,6 @@
9185
<code><![CDATA[$this->db->transStatus]]></code>
9286
</InaccessibleProperty>
9387
</file>
94-
<file src="system/Database/OCI8/Connection.php">
95-
<UndefinedConstant>
96-
<code>OCI_COMMIT_ON_SUCCESS</code>
97-
<code>OCI_COMMIT_ON_SUCCESS</code>
98-
<code>OCI_COMMIT_ON_SUCCESS</code>
99-
<code>OCI_NO_AUTO_COMMIT</code>
100-
<code>SQLT_CHR</code>
101-
</UndefinedConstant>
102-
</file>
10388
<file src="system/Debug/Toolbar/Views/toolbar.tpl.php">
10489
<InaccessibleMethod>
10590
<code>renderTimeline</code>
@@ -132,11 +117,6 @@
132117
<code>#[ReturnTypeWillChange]</code>
133118
</MissingImmutableAnnotation>
134119
</file>
135-
<file src="system/Test/ControllerResponse.php">
136-
<UnsupportedPropertyReferenceUsage>
137-
<code><![CDATA[$this->dom = &$this->domParser]]></code>
138-
</UnsupportedPropertyReferenceUsage>
139-
</file>
140120
<file src="system/View/Parser.php">
141121
<UndefinedDocblockClass>
142122
<code><![CDATA[array<string, array<parser_callable_string>|parser_callable_string|parser_callable>]]></code>
@@ -164,11 +144,6 @@
164144
<code>$this</code>
165145
</InvalidScope>
166146
</file>
167-
<file src="tests/system/CLI/ConsoleTest.php">
168-
<DuplicateArrayKey>
169-
<code>$command</code>
170-
</DuplicateArrayKey>
171-
</file>
172147
<file src="tests/system/CommonFunctionsTest.php">
173148
<UndefinedClass>
174149
<code>UnexsistenceClass</code>
@@ -181,19 +156,6 @@
181156
<code><![CDATA['Config\TestRegistrar']]></code>
182157
</UndefinedClass>
183158
</file>
184-
<file src="tests/system/Database/BaseConnectionTest.php">
185-
<InaccessibleProperty>
186-
<code><![CDATA[$db->username]]></code>
187-
<code><![CDATA[$db->username]]></code>
188-
</InaccessibleProperty>
189-
</file>
190-
<file src="tests/system/Database/Live/OCI8/CallStoredProcedureTest.php">
191-
<UndefinedConstant>
192-
<code>OCI_ASSOC</code>
193-
<code>OCI_B_CURSOR</code>
194-
<code>OCI_RETURN_NULLS</code>
195-
</UndefinedConstant>
196-
</file>
197159
<file src="tests/system/Entity/EntityTest.php">
198160
<EmptyArrayAccess>
199161
<code>$current[$key]</code>

system/DataCaster/Cast/ArrayCast.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
/**
17+
* Class ArrayCast
18+
*
19+
* (PHP) [array --> string] --> (DB driver) --> (DB column) string
20+
* [ <-- string] <-- (DB driver) <-- (DB column) string
21+
*/
22+
class ArrayCast extends BaseCast implements CastInterface
23+
{
24+
public static function get(mixed $value, array $params = []): array
25+
{
26+
if (! is_string($value)) {
27+
self::invalidTypeValueError($value);
28+
}
29+
30+
if ((strpos($value, 'a:') === 0 || strpos($value, 's:') === 0)) {
31+
$value = unserialize($value, ['allowed_classes' => false]);
32+
}
33+
34+
return (array) $value;
35+
}
36+
37+
public static function set(mixed $value, array $params = []): string
38+
{
39+
return serialize($value);
40+
}
41+
}

system/DataCaster/Cast/BaseCast.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
use TypeError;
17+
18+
abstract class BaseCast implements CastInterface
19+
{
20+
public static function get(mixed $value, array $params = []): mixed
21+
{
22+
return $value;
23+
}
24+
25+
public static function set(mixed $value, array $params = []): mixed
26+
{
27+
return $value;
28+
}
29+
30+
protected static function invalidTypeValueError(mixed $value): never
31+
{
32+
$message = '[' . static::class . '] Invalid value type: ' . get_debug_type($value);
33+
if (is_scalar($value)) {
34+
$message .= ', and its value: ' . var_export($value, true);
35+
}
36+
37+
throw new TypeError($message);
38+
}
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
/**
17+
* Class BooleanCast
18+
*
19+
* (PHP) [bool --> bool ] --> (DB driver) --> (DB column) bool|int(0/1)
20+
* [ <-- string|int] <-- (DB driver) <-- (DB column) bool|int(0/1)
21+
*/
22+
class BooleanCast extends BaseCast
23+
{
24+
public static function get(mixed $value, array $params = []): bool
25+
{
26+
// For PostgreSQL
27+
if ($value === 't') {
28+
return true;
29+
}
30+
if ($value === 'f') {
31+
return false;
32+
}
33+
34+
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
35+
}
36+
}

system/DataCaster/Cast/CSVCast.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
/**
17+
* Class CSVCast
18+
*
19+
* (PHP) [array --> string] --> (DB driver) --> (DB column) string
20+
* [ <-- string] <-- (DB driver) <-- (DB column) string
21+
*/
22+
class CSVCast extends BaseCast
23+
{
24+
public static function get(mixed $value, array $params = []): array
25+
{
26+
if (! is_string($value)) {
27+
self::invalidTypeValueError($value);
28+
}
29+
30+
return explode(',', $value);
31+
}
32+
33+
public static function set(mixed $value, array $params = []): string
34+
{
35+
if (! is_array($value)) {
36+
self::invalidTypeValueError($value);
37+
}
38+
39+
return implode(',', $value);
40+
}
41+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
interface CastInterface
17+
{
18+
/**
19+
* Takes a value from DataSource, returns its value for PHP.
20+
*
21+
* @param mixed $value Data from database driver
22+
* @param list<string> $params Additional param
23+
*
24+
* @return mixed PHP native value
25+
*/
26+
public static function get(mixed $value, array $params = []): mixed;
27+
28+
/**
29+
* Takes a PHP value, returns its value for DataSource.
30+
*
31+
* @param mixed $value PHP native value
32+
* @param list<string> $params Additional param
33+
*
34+
* @return mixed Data to pass to database driver
35+
*/
36+
public static function set(mixed $value, array $params = []): mixed;
37+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\DataCaster\Cast;
15+
16+
use CodeIgniter\I18n\Time;
17+
18+
/**
19+
* Class DatetimeCast
20+
*
21+
* (PHP) [Time --> string] --> (DB driver) --> (DB column) datetime
22+
* [ <-- string] <-- (DB driver) <-- (DB column) datetime
23+
*/
24+
class DatetimeCast extends BaseCast
25+
{
26+
public static function get(mixed $value, array $params = []): Time
27+
{
28+
if (! is_string($value)) {
29+
self::invalidTypeValueError($value);
30+
}
31+
32+
/**
33+
* @see https://www.php.net/manual/en/datetimeimmutable.createfromformat.php#datetimeimmutable.createfromformat.parameters
34+
*/
35+
$format = $params[0] ?? 'Y-m-d H:i:s';
36+
37+
return Time::createFromFormat($format, $value);
38+
}
39+
40+
public static function set(mixed $value, array $params = []): string
41+
{
42+
if (! $value instanceof Time) {
43+
self::invalidTypeValueError($value);
44+
}
45+
46+
return (string) $value;
47+
}
48+
}

0 commit comments

Comments
 (0)