Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
sqlsrv_platform
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 4
210
0.00% covered (danger)
0.00%
0 / 1
 getDefaultConstraintDeclarationSQL
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 getAlterTableSQL
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
132
 generate_doctrine_identifier_name
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 generate_doctrine_default_constraint_name
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
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\SQLServerPlatform;
17use Doctrine\DBAL\Schema\Identifier;
18use Doctrine\DBAL\Schema\TableDiff;
19
20/**
21 * SQLServer specific schema restrictions for BC.
22 */
23class sqlsrv_platform extends SQLServerPlatform
24{
25    /**
26     * {@inheritDoc}
27     *
28     * Renames the default constraints to use the classic phpBB's names
29     */
30    public function getDefaultConstraintDeclarationSQL($table, array $column)
31    {
32        $sql = parent::getDefaultConstraintDeclarationSQL($table, $column);
33
34        return str_replace(
35            [
36                $this->generate_doctrine_identifier_name($table),
37                $this->generate_doctrine_identifier_name($column['name']),
38            ], [
39                $table,
40                $column['name'] . '_1',
41            ],
42            $sql);
43    }
44
45    /**
46     * {@inheritDoc}
47     *
48     * Renames the default constraints to use the classic phpBB's names
49     */
50    public function getAlterTableSQL(TableDiff $diff)
51    {
52        $sql = [];
53
54        // When dropping a column, if it has a default we need to drop the default constraint first
55        foreach ($diff->removedColumns as $column)
56        {
57            if (!$column->getAutoincrement())
58            {
59                $sql[] = $this->getDropConstraintSQL($this->generate_doctrine_default_constraint_name($diff->name, $column->getQuotedName($this)), $diff->name);
60            }
61        }
62
63        // When dropping a primary key, the constraint needs to be dropped
64        foreach ($diff->removedIndexes as $key => $index)
65        {
66            if ($index->isPrimary())
67            {
68                unset($diff->removedIndexes[$key]);
69                $sql[] = $this->getDropConstraintSQL($index->getQuotedName($this), $diff->name);
70            }
71        }
72
73        $sql = array_merge($sql, parent::getAlterTableSQL($diff));
74
75        $doctrine_names = [];
76        $phpbb_names = [];
77
78        // OLD Table name
79        $doctrine_names[] = $this->generate_doctrine_identifier_name($diff->name);
80        $phpbb_names[] = $diff->name;
81
82        // NEW Table name if relevant
83        if ($diff->getNewName() !== false)
84        {
85            $doctrine_names[] = $this->generate_doctrine_identifier_name($diff->getNewName()->getName());
86            $phpbb_names[] = $diff->getNewName()->getName();
87        }
88
89        foreach ($diff->addedColumns as $column)
90        {
91            $doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
92            $phpbb_names[] = $column->getQuotedName($this) . '_1';
93        }
94
95        foreach ($diff->removedColumns as $column)
96        {
97            $doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
98            $phpbb_names[] = $column->getQuotedName($this) . '_1';
99        }
100
101        foreach ($diff->renamedColumns as $column)
102        {
103            $doctrine_names[] = $this->generate_doctrine_identifier_name($column->getQuotedName($this));
104            $phpbb_names[] = $column->getQuotedName($this) . '_1';
105        }
106
107        foreach ($diff->changedColumns as $column)
108        {
109            $doctrine_names[] = $this->generate_doctrine_identifier_name($column->column->getQuotedName($this));
110            $phpbb_names[] = $column->column->getQuotedName($this) . '_1';
111
112            if ($column->oldColumnName != $column->column->getQuotedName($this))
113            {
114                $doctrine_names[] = $this->generate_doctrine_identifier_name($column->oldColumnName);
115                $phpbb_names[] = $column->oldColumnName . '_1';
116            }
117        }
118
119        return str_replace($doctrine_names, $phpbb_names, $sql);
120    }
121
122    /**
123     * Returns a hash value for a given identifier.
124     *
125     * @param string $identifier Identifier to generate a hash value for.
126     *
127     * @return string
128     */
129    private function generate_doctrine_identifier_name(string $identifier): string
130    {
131        // Always generate name for unquoted identifiers to ensure consistency.
132        $identifier = new Identifier($identifier);
133
134        return strtoupper(dechex(crc32($identifier->getName())));
135    }
136
137    /**
138     * Returns a unique default constraint name for a table and column.
139     *
140     * @param string $table  Name of the table to generate the unique default constraint name for.
141     * @param string $column Name of the column in the table to generate the unique default constraint name for.
142     *
143     * @return string
144     */
145    private function generate_doctrine_default_constraint_name(string $table, string $column): string
146    {
147        return 'DF_' . $this->generate_doctrine_identifier_name($table) . '_' . $this->generate_doctrine_identifier_name($column);
148    }
149}