Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.76% |
24 / 29 |
|
33.33% |
1 / 3 |
CRAP | |
0.00% |
0 / 1 |
type_converter | |
82.76% |
24 / 29 |
|
33.33% |
1 / 3 |
22.05 | |
0.00% |
0 / 1 |
convert | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
mapWithLength | |
93.75% |
15 / 16 |
|
0.00% |
0 / 1 |
10.02 | |||
mapType | |
55.56% |
5 / 9 |
|
0.00% |
0 / 1 |
13.62 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\db\doctrine; |
15 | |
16 | /** |
17 | * Map phpBB's database types to Doctrine's portable types. |
18 | */ |
19 | class type_converter |
20 | { |
21 | /** |
22 | * Type map. |
23 | * |
24 | * @var array |
25 | */ |
26 | private const TYPE_MAP = [ |
27 | 'INT' => ['integer', []], |
28 | 'BINT' => ['bigint', []], |
29 | 'ULINT' => ['integer', ['unsigned' => true]], |
30 | 'UINT' => ['integer', ['unsigned' => true]], |
31 | 'TINT' => ['smallint', []], |
32 | 'USINT' => ['smallint', ['unsigned' => true]], |
33 | 'BOOL' => ['boolean', ['unsigned' => true]], |
34 | 'VCHAR' => ['string', ['length' => 255]], |
35 | 'CHAR' => ['ascii_string', []], |
36 | 'XSTEXT' => ['ascii_string', ['length' => 1000]], |
37 | 'XSTEXT_UNI'=> ['string', ['length' => 100]], |
38 | 'STEXT' => ['ascii_string', ['length' => 3000]], |
39 | 'STEXT_UNI' => ['string', ['length' => 255]], |
40 | 'TEXT' => ['text', ['length' => ((1 << 16) - 1)]], |
41 | 'TEXT_UNI' => ['text', ['length' => ((1 << 16) - 1)]], |
42 | 'MTEXT' => ['text', ['length' => ((1 << 24) - 1)]], |
43 | 'MTEXT_UNI' => ['text', ['length' => ((1 << 24) - 1)]], |
44 | 'TIMESTAMP' => ['integer', ['unsigned' => true]], |
45 | 'DECIMAL' => ['decimal', ['precision' => 5, 'scale' => 2]], |
46 | 'PDECIMAL' => ['decimal', ['precision' => 6, 'scale' => 3]], |
47 | 'VCHAR_UNI' => ['string', ['length' => 255]], |
48 | 'VCHAR_CI' => ['string_ci', ['length' => 255]], |
49 | 'VARBINARY' => ['binary', ['length' => 255]], |
50 | ]; |
51 | |
52 | /** |
53 | * Convert legacy type to Doctrine's type system. |
54 | * |
55 | * @param string $type Legacy type name |
56 | * |
57 | * @return array<string, array> Pair of type name and options. |
58 | * @psalm-return array{string, array} |
59 | */ |
60 | public static function convert(string $type, string $dbms): array |
61 | { |
62 | if (strpos($type, ':') !== false) |
63 | { |
64 | list($typename, $length) = explode(':', $type); |
65 | return self::mapWithLength($typename, (int) $length); |
66 | } |
67 | |
68 | return self::mapType($type, $dbms); |
69 | } |
70 | |
71 | /** |
72 | * Map legacy types with length attribute. |
73 | * |
74 | * @param string $type Legacy type name. |
75 | * @param int $length Type length. |
76 | * |
77 | * @return array{string, array{string, ...}} Pair of type name and options. |
78 | */ |
79 | private static function mapWithLength(string $type, int $length): array |
80 | { |
81 | switch ($type) |
82 | { |
83 | case 'UINT': |
84 | case 'INT': |
85 | case 'TINT': |
86 | return self::TYPE_MAP[$type]; |
87 | |
88 | case 'DECIMAL': |
89 | case 'PDECIMAL': |
90 | $pair = self::TYPE_MAP[$type]; |
91 | $pair[1]['precision'] = $length; |
92 | return $pair; |
93 | |
94 | case 'VCHAR': |
95 | case 'CHAR': |
96 | case 'VCHAR_UNI': |
97 | $pair = self::TYPE_MAP[$type]; |
98 | $pair[1]['length'] = $length; |
99 | return $pair; |
100 | |
101 | default: |
102 | throw new \InvalidArgumentException("Database type is undefined."); |
103 | } |
104 | } |
105 | |
106 | /** |
107 | * Map phpBB's legacy database types to Doctrine types. |
108 | * |
109 | * @param string $type Type name. |
110 | * |
111 | * @return array{string, array} Pair of type name and an array of options. |
112 | */ |
113 | private static function mapType(string $type, string $dbms): array |
114 | { |
115 | if (!array_key_exists($type, self::TYPE_MAP)) |
116 | { |
117 | throw new \InvalidArgumentException("Database type is undefined."); |
118 | } |
119 | |
120 | // Historically, on mssql varbinary fields were stored as varchar. |
121 | // For compatibility reasons we have to keep it (because when |
122 | // querying the database, mssql does not convert strings to their |
123 | // binary representation automatically like the other dbms. |
124 | if ($type === 'VARBINARY' && $dbms === 'mssql') |
125 | { |
126 | return self::TYPE_MAP['VCHAR']; |
127 | } |
128 | |
129 | // Historically, on mssql bool fields were stored as integer. |
130 | // For compatibility reasons we have to keep it because is |
131 | // some queries we are using MIN() to these columns which |
132 | // is forbidden by MSSQL for bool (bit) columns. |
133 | if ($type === 'BOOL' && $dbms === 'mssql') |
134 | { |
135 | return self::TYPE_MAP['TINT']; |
136 | } |
137 | |
138 | // Historically, on postgres bool fields were stored as integer. |
139 | // For compatibility reasons we have to keep it because when |
140 | // querying the database, postgres does not convert automatically |
141 | // 0 and 1 to their boolean representation like the other dbms. |
142 | if ($type === 'BOOL' && $dbms === 'postgresql') |
143 | { |
144 | return self::TYPE_MAP['TINT']; |
145 | } |
146 | |
147 | return self::TYPE_MAP[$type]; |
148 | } |
149 | } |