1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Doctrine\DBAL\Schema; |
6
|
|
|
|
7
|
|
|
use Doctrine\DBAL\Platforms\SQLAnywherePlatform; |
8
|
|
|
use Doctrine\DBAL\Types\Type; |
9
|
|
|
use function assert; |
10
|
|
|
use function is_string; |
11
|
|
|
use function preg_replace; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* SAP Sybase SQL Anywhere schema manager. |
15
|
|
|
*/ |
16
|
|
|
class SQLAnywhereSchemaManager extends AbstractSchemaManager |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* {@inheritdoc} |
20
|
|
|
* |
21
|
|
|
* Starts a database after creation |
22
|
|
|
* as SQL Anywhere needs a database to be started |
23
|
|
|
* before it can be used. |
24
|
|
|
* |
25
|
|
|
* @see startDatabase |
26
|
|
|
*/ |
27
|
|
|
public function createDatabase(string $database) : void |
28
|
|
|
{ |
29
|
|
|
parent::createDatabase($database); |
30
|
|
|
$this->startDatabase($database); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* {@inheritdoc} |
35
|
|
|
* |
36
|
|
|
* Tries stopping a database before dropping |
37
|
|
|
* as SQL Anywhere needs a database to be stopped |
38
|
|
|
* before it can be dropped. |
39
|
|
|
* |
40
|
|
|
* @see stopDatabase |
41
|
|
|
*/ |
42
|
|
|
public function dropDatabase(string $database) : void |
43
|
|
|
{ |
44
|
|
|
$this->tryMethod('stopDatabase', $database); |
45
|
|
|
parent::dropDatabase($database); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
public function startDatabase(string $database) : void |
49
|
|
|
{ |
50
|
|
|
assert($this->_platform instanceof SQLAnywherePlatform); |
51
|
|
|
$this->_execSql($this->_platform->getStartDatabaseSQL($database)); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
public function stopDatabase(string $database) : void |
55
|
|
|
{ |
56
|
|
|
assert($this->_platform instanceof SQLAnywherePlatform); |
57
|
|
|
$this->_execSql($this->_platform->getStopDatabaseSQL($database)); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* {@inheritdoc} |
62
|
|
|
*/ |
63
|
|
|
protected function _getPortableDatabaseDefinition(array $database) : string |
64
|
|
|
{ |
65
|
|
|
return $database['name']; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* {@inheritdoc} |
70
|
|
|
*/ |
71
|
|
|
protected function _getPortableSequenceDefinition(array $sequence) : Sequence |
72
|
|
|
{ |
73
|
|
|
return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['start_with']); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* {@inheritdoc} |
78
|
|
|
*/ |
79
|
|
|
protected function _getPortableTableColumnDefinition(array $tableColumn) : Column |
80
|
|
|
{ |
81
|
|
|
$type = $this->extractDoctrineTypeFromComment($tableColumn['comment']) |
82
|
|
|
?? $this->_platform->getDoctrineTypeMapping($tableColumn['type']); |
83
|
|
|
|
84
|
|
|
$precision = null; |
85
|
|
|
$scale = null; |
86
|
|
|
$fixed = false; |
87
|
|
|
$default = null; |
88
|
|
|
|
89
|
|
|
if ($tableColumn['default'] !== null) { |
90
|
|
|
// Strip quotes from default value. |
91
|
|
|
$default = preg_replace(["/^'(.*)'$/", "/''/"], ['$1', "'"], $tableColumn['default']); |
92
|
|
|
|
93
|
|
|
if ($default === 'autoincrement') { |
94
|
|
|
$default = null; |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
switch ($tableColumn['type']) { |
99
|
|
|
case 'binary': |
100
|
|
|
case 'char': |
101
|
|
|
case 'nchar': |
102
|
|
|
$fixed = true; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
switch ($type) { |
106
|
|
|
case 'decimal': |
107
|
|
|
case 'float': |
108
|
|
|
$precision = $tableColumn['length']; |
109
|
|
|
$scale = $tableColumn['scale']; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return new Column( |
113
|
|
|
$tableColumn['column_name'], |
114
|
|
|
Type::getType($type), |
115
|
|
|
[ |
116
|
|
|
'length' => $type === 'string' ? $tableColumn['length'] : null, |
117
|
|
|
'precision' => $precision, |
118
|
|
|
'scale' => $scale, |
119
|
|
|
'unsigned' => (bool) $tableColumn['unsigned'], |
120
|
|
|
'fixed' => $fixed, |
121
|
|
|
'notnull' => (bool) $tableColumn['notnull'], |
122
|
|
|
'default' => $default, |
123
|
|
|
'autoincrement' => (bool) $tableColumn['autoincrement'], |
124
|
|
|
'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' |
125
|
|
|
? $tableColumn['comment'] |
126
|
|
|
: null, |
127
|
|
|
] |
128
|
|
|
); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* {@inheritdoc} |
133
|
|
|
*/ |
134
|
|
|
protected function _getPortableTableDefinition(array $table) : string |
135
|
|
|
{ |
136
|
|
|
return $table['table_name']; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* {@inheritdoc} |
141
|
|
|
*/ |
142
|
|
View Code Duplication |
protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey) : ForeignKeyConstraint |
|
|
|
|
143
|
|
|
{ |
144
|
|
|
return new ForeignKeyConstraint( |
145
|
|
|
$tableForeignKey['local_columns'], |
146
|
|
|
$tableForeignKey['foreign_table'], |
147
|
|
|
$tableForeignKey['foreign_columns'], |
148
|
|
|
$tableForeignKey['name'], |
149
|
|
|
$tableForeignKey['options'] |
150
|
|
|
); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* {@inheritdoc} |
155
|
|
|
*/ |
156
|
|
|
protected function _getPortableTableForeignKeysList(array $tableForeignKeys) : array |
157
|
|
|
{ |
158
|
|
|
$foreignKeys = []; |
159
|
|
|
|
160
|
|
|
foreach ($tableForeignKeys as $tableForeignKey) { |
161
|
|
|
if (! isset($foreignKeys[$tableForeignKey['index_name']])) { |
162
|
|
|
$foreignKeys[$tableForeignKey['index_name']] = [ |
163
|
|
|
'local_columns' => [$tableForeignKey['local_column']], |
164
|
|
|
'foreign_table' => $tableForeignKey['foreign_table'], |
165
|
|
|
'foreign_columns' => [$tableForeignKey['foreign_column']], |
166
|
|
|
'name' => $tableForeignKey['index_name'], |
167
|
|
|
'options' => [ |
168
|
|
|
'notnull' => $tableForeignKey['notnull'], |
169
|
|
|
'match' => $tableForeignKey['match'], |
170
|
|
|
'onUpdate' => $tableForeignKey['on_update'], |
171
|
|
|
'onDelete' => $tableForeignKey['on_delete'], |
172
|
|
|
'check_on_commit' => $tableForeignKey['check_on_commit'], |
173
|
|
|
'clustered' => $tableForeignKey['clustered'], |
174
|
|
|
'for_olap_workload' => $tableForeignKey['for_olap_workload'], |
175
|
|
|
], |
176
|
|
|
]; |
177
|
|
View Code Duplication |
} else { |
|
|
|
|
178
|
|
|
$foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column']; |
179
|
|
|
$foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column']; |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
return parent::_getPortableTableForeignKeysList($foreignKeys); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* {@inheritdoc} |
188
|
|
|
*/ |
189
|
|
|
protected function _getPortableTableIndexesList(array $tableIndexRows, string $tableName) : array |
190
|
|
|
{ |
191
|
|
|
foreach ($tableIndexRows as &$tableIndex) { |
192
|
|
|
$tableIndex['primary'] = (bool) $tableIndex['primary']; |
193
|
|
|
$tableIndex['flags'] = []; |
194
|
|
|
|
195
|
|
|
if ($tableIndex['clustered']) { |
196
|
|
|
$tableIndex['flags'][] = 'clustered'; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
if ($tableIndex['with_nulls_not_distinct']) { |
200
|
|
|
$tableIndex['flags'][] = 'with_nulls_not_distinct'; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
if (! $tableIndex['for_olap_workload']) { |
204
|
|
|
continue; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
$tableIndex['flags'][] = 'for_olap_workload'; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
return parent::_getPortableTableIndexesList($tableIndexRows, $tableName); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* {@inheritdoc} |
215
|
|
|
*/ |
216
|
|
|
protected function _getPortableViewDefinition(array $view) : View |
217
|
|
|
{ |
218
|
|
|
$definition = preg_replace('/^.*\s+as\s+SELECT(.*)/i', 'SELECT$1', $view['view_def']); |
219
|
|
|
assert(is_string($definition)); |
220
|
|
|
|
221
|
|
|
return new View($view['table_name'], $definition); |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.