Skip to content

Commit 88ae2a2

Browse files
Merge pull request #17380 from kamil-tekiela/Microoptimizations-for-exportSQL
Refactor ExportSql::exportData()
2 parents 76899ac + 4dabcf0 commit 88ae2a2

6 files changed

Lines changed: 68 additions & 105 deletions

File tree

libraries/classes/DatabaseInterface.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,13 +2122,13 @@ public function getFieldsMeta(ResultInterface $result): array
21222122
*
21232123
* @return string a MySQL escaped string
21242124
*/
2125-
public function escapeString(string $str, $link = self::CONNECT_USER)
2125+
public function escapeString(string $str, $link = self::CONNECT_USER): string
21262126
{
2127-
if ($this->extension === null || ! isset($this->links[$link])) {
2128-
return $str;
2127+
if (isset($this->links[$link])) {
2128+
return $this->extension->escapeString($this->links[$link], $str);
21292129
}
21302130

2131-
return $this->extension->escapeString($this->links[$link], $str);
2131+
return $str;
21322132
}
21332133

21342134
/**

libraries/classes/Dbal/DbalInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ public function getFieldsMeta(ResultInterface $result): array;
632632
*
633633
* @return string a MySQL escaped string
634634
*/
635-
public function escapeString(string $str, $link = DatabaseInterface::CONNECT_USER);
635+
public function escapeString(string $str, $link = DatabaseInterface::CONNECT_USER): string;
636636

637637
/**
638638
* returns properly escaped string for use in MySQL LIKE clauses

libraries/classes/Plugins/Export/ExportSql.php

Lines changed: 53 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -646,11 +646,11 @@ public function exportRoutines($db, array $aliases = []): bool
646646
*
647647
* @return string The formatted comment
648648
*/
649-
private function exportComment($text = '')
649+
private function exportComment(string $text = ''): string
650650
{
651651
if (isset($GLOBALS['sql_include_comments']) && $GLOBALS['sql_include_comments']) {
652652
// see https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
653-
if (empty($text)) {
653+
if ($text === '') {
654654
return '--' . $GLOBALS['crlf'];
655655
}
656656

@@ -840,11 +840,7 @@ public function exportDBCreate($db, $exportType, $dbAlias = ''): bool
840840
$dbAlias = $db;
841841
}
842842

843-
if (isset($GLOBALS['sql_compatibility'])) {
844-
$compat = $GLOBALS['sql_compatibility'];
845-
} else {
846-
$compat = 'NONE';
847-
}
843+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
848844

849845
if (isset($GLOBALS['sql_drop_database'])) {
850846
if (
@@ -928,11 +924,7 @@ public function exportDBHeader($db, $dbAlias = ''): bool
928924
$dbAlias = $db;
929925
}
930926

931-
if (isset($GLOBALS['sql_compatibility'])) {
932-
$compat = $GLOBALS['sql_compatibility'];
933-
} else {
934-
$compat = 'NONE';
935-
}
927+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
936928

937929
$head = $this->exportComment()
938930
. $this->exportComment(
@@ -955,8 +947,6 @@ public function exportDBHeader($db, $dbAlias = ''): bool
955947
*/
956948
public function exportDBFooter($db): bool
957949
{
958-
$GLOBALS['crlf'] = $GLOBALS['crlf'] ?? null;
959-
960950
$result = true;
961951

962952
//add indexes to the sql dump file
@@ -1293,20 +1283,17 @@ public function getTableDefStandIn($db, $view, $crlf, $aliases = [])
12931283
/**
12941284
* Returns CREATE definition that matches $view's structure
12951285
*
1296-
* @param string $db the database name
1297-
* @param string $view the view name
1298-
* @param string $crlf the end of line sequence
1299-
* @param bool $addSemicolon whether to add semicolon and end-of-line at
1300-
* the end
1301-
* @param array $aliases Aliases of db/table/columns
1286+
* @param string $db the database name
1287+
* @param string $view the view name
1288+
* @param string $crlf the end of line sequence
1289+
* @param array $aliases Aliases of db/table/columns
13021290
*
13031291
* @return string resulting schema
13041292
*/
13051293
private function getTableDefForView(
13061294
$db,
13071295
$view,
13081296
$crlf,
1309-
$addSemicolon = true,
13101297
array $aliases = []
13111298
) {
13121299
$dbAlias = $db;
@@ -1361,13 +1348,9 @@ private function getTableDefForView(
13611348
$firstCol = false;
13621349
}
13631350

1364-
$createQuery .= $crlf . ')' . ($addSemicolon ? ';' : '') . $crlf;
1351+
$createQuery .= $crlf . ');' . $crlf;
13651352

1366-
if (isset($GLOBALS['sql_compatibility'])) {
1367-
$compat = $GLOBALS['sql_compatibility'];
1368-
} else {
1369-
$compat = 'NONE';
1370-
}
1353+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
13711354

13721355
if ($compat === 'MSSQL') {
13731356
$createQuery = $this->makeCreateTableMSSQLCompatible($createQuery);
@@ -1422,11 +1405,7 @@ public function getTableDef(
14221405
$schemaCreate = '';
14231406
$newCrlf = $crlf;
14241407

1425-
if (isset($GLOBALS['sql_compatibility'])) {
1426-
$compat = $GLOBALS['sql_compatibility'];
1427-
} else {
1428-
$compat = 'NONE';
1429-
}
1408+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
14301409

14311410
$result = $GLOBALS['dbi']->tryQuery(
14321411
'SHOW TABLE STATUS FROM ' . Util::backquote($db)
@@ -2046,11 +2025,7 @@ public function exportStructure(
20462025
$dbAlias = $db;
20472026
$tableAlias = $table;
20482027
$this->initAlias($aliases, $dbAlias, $tableAlias);
2049-
if (isset($GLOBALS['sql_compatibility'])) {
2050-
$compat = $GLOBALS['sql_compatibility'];
2051-
} else {
2052-
$compat = 'NONE';
2053-
}
2028+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
20542029

20552030
$formattedTableName = Util::backquoteCompat($tableAlias, $compat, isset($GLOBALS['sql_backquotes']));
20562031
$dump = $this->possibleCRLF()
@@ -2138,7 +2113,7 @@ public function exportStructure(
21382113
. Util::backquote($tableAlias) . ';' . $crlf;
21392114
}
21402115

2141-
$dump .= $this->getTableDefForView($db, $table, $crlf, true, $aliases);
2116+
$dump .= $this->getTableDefForView($db, $table, $crlf, $aliases);
21422117
}
21432118

21442119
break;
@@ -2179,7 +2154,6 @@ public function exportData(
21792154
$sqlQuery,
21802155
array $aliases = []
21812156
): bool {
2182-
$GLOBALS['current_row'] = $GLOBALS['current_row'] ?? null;
21832157
$GLOBALS['sql_backquotes'] = $GLOBALS['sql_backquotes'] ?? null;
21842158

21852159
// Do not export data for merge tables
@@ -2191,11 +2165,7 @@ public function exportData(
21912165
$tableAlias = $table;
21922166
$this->initAlias($aliases, $dbAlias, $tableAlias);
21932167

2194-
if (isset($GLOBALS['sql_compatibility'])) {
2195-
$compat = $GLOBALS['sql_compatibility'];
2196-
} else {
2197-
$compat = 'NONE';
2198-
}
2168+
$compat = $GLOBALS['sql_compatibility'] ?? 'NONE';
21992169

22002170
$formattedTableName = Util::backquoteCompat($tableAlias, $compat, $GLOBALS['sql_backquotes']);
22012171

@@ -2311,7 +2281,7 @@ public function exportData(
23112281
}
23122282

23132283
//\x08\\x09, not required
2314-
$GLOBALS['current_row'] = 0;
2284+
$current_row = 0;
23152285
$querySize = 0;
23162286
if (
23172287
($GLOBALS['sql_insert_syntax'] === 'extended'
@@ -2326,7 +2296,7 @@ public function exportData(
23262296
}
23272297

23282298
while ($row = $result->fetchRow()) {
2329-
if ($GLOBALS['current_row'] == 0) {
2299+
if ($current_row === 0) {
23302300
$head = $this->possibleCRLF()
23312301
. $this->exportComment()
23322302
. $this->exportComment(
@@ -2342,9 +2312,9 @@ public function exportData(
23422312

23432313
// We need to SET IDENTITY_INSERT ON for MSSQL
23442314
if (
2345-
isset($GLOBALS['sql_compatibility'])
2315+
$current_row === 0
2316+
&& isset($GLOBALS['sql_compatibility'])
23462317
&& $GLOBALS['sql_compatibility'] === 'MSSQL'
2347-
&& $GLOBALS['current_row'] == 0
23482318
) {
23492319
if (
23502320
! $this->export->outputHandler(
@@ -2361,22 +2331,22 @@ public function exportData(
23612331
}
23622332
}
23632333

2364-
$GLOBALS['current_row']++;
2334+
$current_row++;
23652335
$values = [];
2366-
for ($j = 0; $j < $fieldsCnt; $j++) {
2336+
foreach ($fieldsMeta as $j => $metaInfo) {
23672337
// NULL
2368-
if (! isset($row[$j])) {
2338+
if ($row[$j] === null) {
23692339
$values[] = 'NULL';
23702340
} elseif (
2371-
$fieldsMeta[$j]->isNumeric
2372-
&& ! $fieldsMeta[$j]->isMappedTypeTimestamp
2373-
&& ! $fieldsMeta[$j]->isBlob
2341+
$metaInfo->isNumeric
2342+
&& ! $metaInfo->isMappedTypeTimestamp
2343+
&& ! $metaInfo->isBlob
23742344
) {
23752345
// a number
23762346
// timestamp is numeric on some MySQL 4.1, BLOBs are
23772347
// sometimes numeric
23782348
$values[] = $row[$j];
2379-
} elseif ($fieldsMeta[$j]->isBinary && isset($GLOBALS['sql_hex_for_binary'])) {
2349+
} elseif ($metaInfo->isBinary && isset($GLOBALS['sql_hex_for_binary'])) {
23802350
// a true BLOB
23812351
// - mysqldump only generates hex data when the --hex-blob
23822352
// option is used, for fields having the binary attribute
@@ -2391,16 +2361,16 @@ public function exportData(
23912361
} else {
23922362
$values[] = '0x' . bin2hex($row[$j]);
23932363
}
2394-
} elseif ($fieldsMeta[$j]->isMappedTypeBit) {
2364+
} elseif ($metaInfo->isMappedTypeBit) {
23952365
// detection of 'bit' works only on mysqli extension
23962366
$values[] = "b'" . $GLOBALS['dbi']->escapeString(
23972367
Util::printableBitValue(
23982368
(int) $row[$j],
2399-
(int) $fieldsMeta[$j]->length
2369+
$metaInfo->length
24002370
)
24012371
)
24022372
. "'";
2403-
} elseif ($fieldsMeta[$j]->isMappedTypeGeometry) {
2373+
} elseif ($metaInfo->isMappedTypeGeometry) {
24042374
// export GIS types as hex
24052375
$values[] = '0x' . bin2hex($row[$j]);
24062376
} elseif (! empty($GLOBALS['exporting_metadata']) && $row[$j] === '@LAST_PAGE') {
@@ -2436,45 +2406,38 @@ public function exportData(
24362406
);
24372407
$insertLine .= ' WHERE ' . $tmpUniqueCondition;
24382408
unset($tmpUniqueCondition, $tmpClauseIsUnique);
2439-
} else {
2409+
} elseif ($GLOBALS['sql_insert_syntax'] === 'extended' || $GLOBALS['sql_insert_syntax'] === 'both') {
24402410
// Extended inserts case
2441-
if ($GLOBALS['sql_insert_syntax'] === 'extended' || $GLOBALS['sql_insert_syntax'] === 'both') {
2442-
if ($GLOBALS['current_row'] == 1) {
2443-
$insertLine = $schemaInsert . '('
2444-
. implode(', ', $values) . ')';
2445-
} else {
2446-
$insertLine = '(' . implode(', ', $values) . ')';
2447-
$insertLineSize = mb_strlen($insertLine);
2448-
$sqlMaxSize = $GLOBALS['sql_max_query_size'];
2449-
if (isset($sqlMaxSize) && $sqlMaxSize > 0 && $querySize + $insertLineSize > $sqlMaxSize) {
2450-
if (! $this->export->outputHandler(';' . $crlf)) {
2451-
return false;
2452-
}
2453-
2454-
$querySize = 0;
2455-
$GLOBALS['current_row'] = 1;
2456-
$insertLine = $schemaInsert . $insertLine;
2411+
if ($current_row === 1) {
2412+
$insertLine = $schemaInsert . '('
2413+
. implode(', ', $values) . ')';
2414+
} else {
2415+
$insertLine = '(' . implode(', ', $values) . ')';
2416+
$insertLineSize = mb_strlen($insertLine);
2417+
$sqlMaxSize = $GLOBALS['sql_max_query_size'];
2418+
if ($sqlMaxSize > 0 && $querySize + $insertLineSize > $sqlMaxSize) {
2419+
if (! $this->export->outputHandler(';' . $crlf)) {
2420+
return false;
24572421
}
2458-
}
24592422

2460-
$querySize += mb_strlen($insertLine);
2461-
// Other inserts case
2462-
} else {
2463-
$insertLine = $schemaInsert
2464-
. '(' . implode(', ', $values) . ')';
2423+
$querySize = 0;
2424+
$current_row = 1;
2425+
$insertLine = $schemaInsert . $insertLine;
2426+
}
24652427
}
2466-
}
24672428

2468-
unset($values);
2429+
$querySize += mb_strlen($insertLine);
2430+
} else {
2431+
// Other inserts case
2432+
$insertLine = $schemaInsert . '(' . implode(', ', $values) . ')';
2433+
}
24692434

2470-
if (
2471-
! $this->export->outputHandler(($GLOBALS['current_row'] == 1 ? '' : $separator . $crlf) . $insertLine)
2472-
) {
2435+
if (! $this->export->outputHandler(($current_row === 1 ? '' : $separator . $crlf) . $insertLine)) {
24732436
return false;
24742437
}
24752438
}
24762439

2477-
if ($GLOBALS['current_row'] > 0) {
2440+
if ($current_row > 0) {
24782441
if (! $this->export->outputHandler(';' . $crlf)) {
24792442
return false;
24802443
}
@@ -2484,7 +2447,7 @@ public function exportData(
24842447
if (
24852448
isset($GLOBALS['sql_compatibility'])
24862449
&& $GLOBALS['sql_compatibility'] === 'MSSQL'
2487-
&& $GLOBALS['current_row'] > 0
2450+
&& $current_row > 0
24882451
) {
24892452
$outputSucceeded = $this->export->outputHandler(
24902453
$crlf . 'SET IDENTITY_INSERT '
@@ -2510,7 +2473,7 @@ public function exportData(
25102473
*
25112474
* @return string MSSQL compatible create table statement
25122475
*/
2513-
private function makeCreateTableMSSQLCompatible($createQuery)
2476+
private function makeCreateTableMSSQLCompatible(string $createQuery)
25142477
{
25152478
// In MSSQL
25162479
// 1. No 'IF NOT EXISTS' in CREATE TABLE
@@ -2521,7 +2484,7 @@ private function makeCreateTableMSSQLCompatible($createQuery)
25212484
// 5. No KEY and INDEX inside CREATE TABLE
25222485
// 6. DOUBLE field doesn't exists, we will use FLOAT instead
25232486

2524-
$createQuery = (string) preg_replace('/^CREATE TABLE IF NOT EXISTS/', 'CREATE TABLE', (string) $createQuery);
2487+
$createQuery = (string) preg_replace('/^CREATE TABLE IF NOT EXISTS/', 'CREATE TABLE', $createQuery);
25252488
// first we need to replace all lines ended with '" DATE ...,\n'
25262489
// last preg_replace preserve us from situation with date text
25272490
// inside DEFAULT field value

psalm-baseline.xml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5733,9 +5733,6 @@
57335733
</PossiblyNullReference>
57345734
</file>
57355735
<file src="libraries/classes/DatabaseInterface.php">
5736-
<DocblockTypeContradiction occurrences="1">
5737-
<code>$this-&gt;extension === null</code>
5738-
</DocblockTypeContradiction>
57395736
<EmptyArrayAccess occurrences="1">
57405737
<code>$resultTarget[]</code>
57415738
</EmptyArrayAccess>
@@ -10017,8 +10014,10 @@
1001710014
<code>$oneKey['ref_index_list'][$index]</code>
1001810015
<code>$values[$val]</code>
1001910016
</MixedArrayOffset>
10020-
<MixedAssignment occurrences="37">
10021-
<code>$GLOBALS['current_row']</code>
10017+
<MixedArrayTypeCoercion occurrences="1">
10018+
<code>$row[$j]</code>
10019+
</MixedArrayTypeCoercion>
10020+
<MixedAssignment occurrences="36">
1002210021
<code>$GLOBALS['sql_auto_increments']</code>
1002310022
<code>$GLOBALS['sql_backquotes']</code>
1002410023
<code>$GLOBALS['sql_backquotes']</code>
@@ -10125,9 +10124,7 @@
1012510124
<PropertyTypeCoercion occurrences="1">
1012610125
<code>$field-&gt;key-&gt;columns</code>
1012710126
</PropertyTypeCoercion>
10128-
<RedundantCastGivenDocblockType occurrences="3">
10129-
<code>(int) $fieldsMeta[$j]-&gt;length</code>
10130-
<code>(string) $createQuery</code>
10127+
<RedundantCastGivenDocblockType occurrences="1">
1013110128
<code>(string) $table</code>
1013210129
</RedundantCastGivenDocblockType>
1013310130
<RedundantCondition occurrences="1">

test/classes/Plugins/Export/ExportSqlTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,12 +740,12 @@ public function testGetTableDefForView(): void
740740
);
741741
$GLOBALS['dbi'] = $dbi;
742742

743-
$result = $method->invoke($this->object, 'db', 'view', "\n", false);
743+
$result = $method->invoke($this->object, 'db', 'view', "\n");
744744

745745
$this->assertEquals(
746746
"CREATE TABLE IF NOT EXISTS `view`(\n" .
747747
" `fname` char COLLATE utf-8 DEFAULT NULL COMMENT 'cmt'\n" .
748-
")\n",
748+
");\n",
749749
$result
750750
);
751751
}

0 commit comments

Comments
 (0)