generateIdentifierName()   D
last analyzed

Complexity

Conditions 10
Paths 13

Size

Total Lines 46
Code Lines 30

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 46
rs 4.983
cc 10
eloc 30
nc 13
nop 5

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace RDV\Bundle\MigrationBundle\Tools;
4
5
class DbIdentifierNameGenerator
6
{
7
    /**
8
     * Gets the max size of an identifier
9
     *
10
     * @return int
11
     */
12
    public function getMaxIdentifierSize()
13
    {
14
        return 30;
15
    }
16
17
    /**
18
     * Builds an index name
19
     *
20
     * @param string   $tableName
21
     * @param string[] $columnNames
22
     * @param bool     $uniqueIndex
23
     * @param bool     $forceHash   If FALSE a human readable name is generated if it is possible
24
     *                              If TRUE a name is generated based on a hash (Doctrine standard behaviour)
25
     * @return string
26
     */
27
    public function generateIndexName($tableName, $columnNames, $uniqueIndex = false, $forceHash = false)
28
    {
29
        return $this->generateIdentifierName(
30
            $tableName,
31
            $columnNames,
32
            $uniqueIndex ? 'UNIQ' : 'IDX',
33
            null,
34
            $forceHash
35
        );
36
    }
37
38
    /**
39
     * Builds a foreign key constraint name
40
     *
41
     * @param string   $tableName
42
     * @param string[] $columnNames
43
     * @param bool     $forceHash   If FALSE a human readable name is generated if it is possible
44
     *                              If TRUE a name is generated based on a hash (Doctrine standard behaviour)
45
     * @return string
46
     */
47
    public function generateForeignKeyConstraintName($tableName, $columnNames, $forceHash = false)
48
    {
49
        return $this->generateIdentifierName(
50
            $tableName,
51
            $columnNames,
52
            'FK',
53
            null,
54
            $forceHash
55
        );
56
    }
57
58
    /**
59
     * Generates an identifier from a list of column names obeying a certain string length.
60
     *
61
     * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
62
     * however building identifiers automatically for foreign keys, composite keys or such can easily create
63
     * very long names.
64
     *
65
     * @param string|string[] $tableNames A table name or a list of table names
66
     * @param string[]        $columnNames
67
     * @param string          $prefix
68
     * @param bool|null       $upperCase  If TRUE the returned string is in upper case;
69
     *                                    If FALSE the returned string is in lower case;
70
     *                                    If NULL the encoded name id in upper case, not encoded is in lower case
71
     * @param bool            $forceHash  If FALSE a human readable name is generated if it is possible
72
     *                                    If TRUE a name is generated based on a hash (Doctrine standard behaviour)
73
     * @return string
74
     * @throws \InvalidArgumentException
75
     *
76
     * @SuppressWarnings(PHPMD.NPathComplexity)
77
     */
78
    public function generateIdentifierName(
79
        $tableNames,
80
        $columnNames,
81
        $prefix = '',
82
        $upperCase = null,
83
        $forceHash = false
84
    ) {
85
        if (empty($tableNames) || (is_array($tableNames) && count($tableNames) === 1 && empty($tableNames[0]))) {
86
            throw new \InvalidArgumentException('A table name must not be empty.');
87
        }
88
        if (!is_array($tableNames)) {
89
            $tableNames = [$tableNames];
90
        }
91
92
        if (!$forceHash) {
93
            $columns = implode('_', $columnNames);
94
            $tables  = implode('_', $tableNames);
95
            if (strlen($prefix) + strlen($tables) + strlen($columns) + 2 <= $this->getMaxIdentifierSize()) {
96
                $result = $prefix . '_' . $tables . '_' . $columns;
97
98
                return $upperCase === true ? strtoupper($result) : strtolower($result);
99
            }
100
        }
101
102
        $result = $prefix . '_' .
103
            implode(
104
                '',
105
                array_merge(
106
                    array_map(
107
                        function ($name) {
108
                            return dechex(crc32($name));
109
                        },
110
                        $tableNames
111
                    ),
112
                    array_map(
113
                        function ($name) {
114
                            return dechex(crc32($name));
115
                        },
116
                        $columnNames
117
                    )
118
                )
119
            );
120
        $result = substr($result, 0, $this->getMaxIdentifierSize());
121
122
        return $upperCase === false ? strtolower($result) : strtoupper($result);
123
    }
124
}
125