Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
oracle_platform
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 9
420
0.00% covered (danger)
0.00%
0 / 1
 getVarcharTypeDeclarationSQL
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 getAsciiStringTypeDeclarationSQL
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCreateIndexSQL
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 check_index_name_length
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 getIdentitySequenceName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCreateAutoincrementSql
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 doctrine_normalize_identifier
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 get_doctrine_autoincrement_identifier_name
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 add_doctrine_suffix
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
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
16use Doctrine\DBAL\Platforms\OraclePlatform;
17use Doctrine\DBAL\Schema\Identifier;
18use Doctrine\DBAL\Schema\Index;
19use Doctrine\DBAL\Schema\Table;
20
21/**
22 * Oracle specific schema restrictions for BC.
23 */
24class oracle_platform extends OraclePlatform
25{
26    /**
27     * {@inheritDoc}
28     */
29    public function getVarcharTypeDeclarationSQL(array $column): string
30    {
31        if (array_key_exists('length', $column) && is_int($column['length']))
32        {
33            $column['length'] *= 3;
34        }
35
36        return parent::getVarcharTypeDeclarationSQL($column);
37    }
38
39    /**
40     * {@inheritDoc}
41     */
42    public function getAsciiStringTypeDeclarationSQL(array $column): string
43    {
44        return parent::getVarcharTypeDeclarationSQL($column);
45    }
46
47    /**
48     * {@inheritDoc}
49     */
50    public function getCreateIndexSQL(Index $index, $table): string
51    {
52        if ($table instanceof Table)
53        {
54            $table_name = $table->getName();
55        }
56        else
57        {
58            $table_name = $table;
59        }
60
61        $index_name = $index->getName();
62        if (strpos($index->getName(), $table_name) !== 0)
63        {
64            $index_name = $table_name . '_' . $index->getName();
65        }
66
67        $index = new Index(
68            $this->check_index_name_length($table_name, $index_name),
69            $index->getColumns(),
70            $index->isUnique(),
71            $index->isPrimary(),
72            $index->getFlags(),
73            $index->getOptions()
74        );
75
76        return parent::getCreateIndexSQL($index, $table);
77    }
78
79    /**
80     * Check whether the index name is too long
81     *
82     * @param string    $table_name
83     * @param string    $index_name
84     * @param bool        $throw_error
85     * @return string    The index name, shortened if too long
86     */
87    protected function check_index_name_length(string $table_name, string $index_name, bool $throw_error = true): string
88    {
89        $max_index_name_length = $this->getMaxIdentifierLength();
90        if (strlen($index_name) > $max_index_name_length)
91        {
92            // Try removing the table prefix if it's at the beginning
93            $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)
94            if (strpos($index_name, $table_prefix) === 0)
95            {
96                $index_name = substr($index_name, strlen($table_prefix));
97                return $this->check_index_name_length($table_name, $index_name, $throw_error);
98            }
99
100            // Try removing the remaining suffix part of table name then
101            $table_suffix = substr($table_name, strlen($table_prefix));
102            if (strpos($index_name, $table_suffix) === 0)
103            {
104                // Remove the suffix and underscore separator between table_name and index_name
105                $index_name = substr($index_name, strlen($table_suffix) + 1);
106                return $this->check_index_name_length($table_name, $index_name, $throw_error);
107            }
108
109            if ($throw_error)
110            {
111                throw new \InvalidArgumentException(
112                    "Index name '$index_name' on table '$table_name' is too long. The maximum is $max_index_name_length characters."
113                );
114            }
115        }
116
117        return $index_name;
118    }
119
120    /**
121     * {@inheritdoc}
122     */
123    public function getIdentitySequenceName($tableName, $columnName): string
124    {
125        return $tableName . '_SEQ';
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    public function getCreateAutoincrementSql($name, $table, $start = 1)
132    {
133        $sql = parent::getCreateAutoincrementSql($name, $table, $start);
134
135        return str_replace(
136            $this->get_doctrine_autoincrement_identifier_name($this->doctrine_normalize_identifier($table)),
137            'T_'.$table,
138            $sql
139        );
140    }
141
142    /**
143     * @see OraclePlatform::normalizeIdentifier()
144     */
145    private function doctrine_normalize_identifier($name): Identifier
146    {
147        $identifier = new Identifier($name);
148
149        return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name));
150    }
151
152    /**
153     * @see OraclePlatform::getAutoincrementIdentifierName()
154     */
155    private function get_doctrine_autoincrement_identifier_name(Identifier $table): string
156    {
157        $identifierName = $this->add_doctrine_suffix($table->getName(), '_AI_PK');
158
159        return $table->isQuoted()
160            ? $this->quoteSingleIdentifier($identifierName)
161            : $identifierName;
162    }
163
164    /**
165     * @see OraclePlatform::addSuffix()
166     */
167    private function add_doctrine_suffix(string $identifier, string $suffix): string
168    {
169        $maxPossibleLengthWithoutSuffix = $this->getMaxIdentifierLength() - strlen($suffix);
170        if (strlen($identifier) > $maxPossibleLengthWithoutSuffix)
171        {
172            $identifier = substr($identifier, 0, $maxPossibleLengthWithoutSuffix);
173        }
174
175        return $identifier . $suffix;
176    }
177}