Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.76% covered (warning)
82.76%
24 / 29
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
type_converter
82.76% covered (warning)
82.76%
24 / 29
33.33% covered (danger)
33.33%
1 / 3
22.05
0.00% covered (danger)
0.00%
0 / 1
 convert
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 mapWithLength
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
10.02
 mapType
55.56% covered (warning)
55.56%
5 / 9
0.00% covered (danger)
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
14namespace phpbb\db\doctrine;
15
16/**
17 * Map phpBB's database types to Doctrine's portable types.
18 */
19class 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}