5
5
namespace Doctrine \DBAL \Schema ;
6
6
7
7
use Doctrine \DBAL \Platforms \AbstractPlatform ;
8
+ use Doctrine \DBAL \Schema \Name \Parser ;
9
+ use Doctrine \DBAL \Schema \Name \Parser \Identifier ;
10
+ use Doctrine \Deprecations \Deprecation ;
8
11
9
12
use function array_map ;
13
+ use function count ;
10
14
use function crc32 ;
11
15
use function dechex ;
12
16
use function explode ;
13
17
use function implode ;
18
+ use function sprintf ;
14
19
use function str_contains ;
15
20
use function str_replace ;
16
21
use function strtolower ;
@@ -35,11 +40,18 @@ abstract class AbstractAsset
35
40
36
41
protected bool $ _quoted = false ;
37
42
43
+ /** @var list<Identifier> */
44
+ private array $ identifiers = [];
45
+
46
+ private bool $ validateFuture = false ;
47
+
38
48
/**
39
49
* Sets the name of this asset.
40
50
*/
41
51
protected function _setName (string $ name ): void
42
52
{
53
+ $ input = $ name ;
54
+
43
55
if ($ this ->isIdentifierQuoted ($ name )) {
44
56
$ this ->_quoted = true ;
45
57
$ name = $ this ->trimQuotes ($ name );
@@ -52,6 +64,81 @@ protected function _setName(string $name): void
52
64
}
53
65
54
66
$ this ->_name = $ name ;
67
+
68
+ $ this ->validateFuture = false ;
69
+
70
+ if ($ input !== '' ) {
71
+ $ parser = new Parser ();
72
+
73
+ try {
74
+ $ identifiers = $ parser ->parse ($ input );
75
+ } catch (Parser \Exception $ e ) {
76
+ Deprecation::trigger (
77
+ 'doctrine/dbal ' ,
78
+ 'https://github.com/doctrine/dbal/pull/6592 ' ,
79
+ 'Unable to parse object name: %s. ' ,
80
+ $ e ->getMessage (),
81
+ );
82
+
83
+ return ;
84
+ }
85
+ } else {
86
+ $ identifiers = [];
87
+ }
88
+
89
+ switch (count ($ identifiers )) {
90
+ case 0 :
91
+ $ this ->identifiers = [];
92
+
93
+ return ;
94
+ case 1 :
95
+ $ namespace = null ;
96
+ $ name = $ identifiers [0 ];
97
+ break ;
98
+
99
+ case 2 :
100
+ /** @psalm-suppress PossiblyUndefinedArrayOffset */
101
+ [$ namespace , $ name ] = $ identifiers ;
102
+ break ;
103
+
104
+ default :
105
+ Deprecation::trigger (
106
+ 'doctrine/dbal ' ,
107
+ 'https://github.com/doctrine/dbal/pull/6592 ' ,
108
+ 'An object name may consist of at most 2 identifiers (<namespace>.<name>), %d given. ' ,
109
+ count ($ identifiers ),
110
+ );
111
+
112
+ return ;
113
+ }
114
+
115
+ $ this ->identifiers = $ identifiers ;
116
+ $ this ->validateFuture = true ;
117
+
118
+ $ futureName = $ name ->getValue ();
119
+ $ futureNamespace = $ namespace ?->getValue();
120
+
121
+ if ($ this ->_name !== $ futureName ) {
122
+ Deprecation::trigger (
123
+ 'doctrine/dbal ' ,
124
+ 'https://github.com/doctrine/dbal/pull/6592 ' ,
125
+ 'Instead of "%s", this name will be interpreted as "%s" in 5.0 ' ,
126
+ $ this ->_name ,
127
+ $ futureName ,
128
+ );
129
+ }
130
+
131
+ if ($ this ->_namespace === $ futureNamespace ) {
132
+ return ;
133
+ }
134
+
135
+ Deprecation::trigger (
136
+ 'doctrine/dbal ' ,
137
+ 'https://github.com/doctrine/dbal/pull/6592 ' ,
138
+ 'Instead of %s, the namespace in this name will be interpreted as %s in 5.0. ' ,
139
+ $ this ->_namespace !== null ? sprintf ('"%s" ' , $ this ->_namespace ) : 'null ' ,
140
+ $ futureNamespace !== null ? sprintf ('"%s" ' , $ futureNamespace ) : 'null ' ,
141
+ );
55
142
}
56
143
57
144
/**
@@ -129,12 +216,47 @@ public function getName(): string
129
216
public function getQuotedName (AbstractPlatform $ platform ): string
130
217
{
131
218
$ keywords = $ platform ->getReservedKeywordsList ();
132
- $ parts = explode ('. ' , $ this ->getName ());
133
- foreach ($ parts as $ k => $ v ) {
134
- $ parts [$ k ] = $ this ->_quoted || $ keywords ->isKeyword ($ v ) ? $ platform ->quoteSingleIdentifier ($ v ) : $ v ;
219
+ $ parts = $ normalizedParts = [];
220
+
221
+ foreach (explode ('. ' , $ this ->getName ()) as $ identifier ) {
222
+ $ isQuoted = $ this ->_quoted || $ keywords ->isKeyword ($ identifier );
223
+
224
+ if (! $ isQuoted ) {
225
+ $ parts [] = $ identifier ;
226
+ $ normalizedParts [] = $ platform ->normalizeUnquotedIdentifier ($ identifier );
227
+ } else {
228
+ $ parts [] = $ platform ->quoteSingleIdentifier ($ identifier );
229
+ $ normalizedParts [] = $ identifier ;
230
+ }
231
+ }
232
+
233
+ $ name = implode ('. ' , $ parts );
234
+
235
+ if ($ this ->validateFuture ) {
236
+ $ futureParts = array_map (static function (Identifier $ identifier ) use ($ platform ): string {
237
+ $ value = $ identifier ->getValue ();
238
+
239
+ if (! $ identifier ->isQuoted ()) {
240
+ $ value = $ platform ->normalizeUnquotedIdentifier ($ value );
241
+ }
242
+
243
+ return $ value ;
244
+ }, $ this ->identifiers );
245
+
246
+ if ($ normalizedParts !== $ futureParts ) {
247
+ Deprecation::trigger (
248
+ 'doctrine/dbal ' ,
249
+ 'https://github.com/doctrine/dbal/pull/6592 ' ,
250
+ 'Relying on implicitly quoted identifiers preserving their original case is deprecated. '
251
+ . 'The current name %s will become %s in 5.0. '
252
+ . 'Please quote the name if the case needs to be preserved. ' ,
253
+ $ name ,
254
+ implode ('. ' , array_map ([$ platform , 'quoteSingleIdentifier ' ], $ futureParts )),
255
+ );
256
+ }
135
257
}
136
258
137
- return implode ( ' . ' , $ parts ) ;
259
+ return $ name ;
138
260
}
139
261
140
262
/**
0 commit comments