|
39 | 39 | use Throwable; |
40 | 40 |
|
41 | 41 | use function __; |
| 42 | +use function array_map; |
| 43 | +use function array_reduce; |
42 | 44 | use function array_reverse; |
43 | 45 | use function array_search; |
44 | 46 | use function array_slice; |
@@ -326,15 +328,15 @@ private function displayTableList(array $replicaInfo): string |
326 | 328 | $updateTime = null; |
327 | 329 | if ($this->config->config->ShowDbStructureLastUpdate && isset($currentTable['Update_time'])) { |
328 | 330 | $updateTime = $this->createDateTime($currentTable['Update_time']); |
329 | | - if ($updateTime !== null && ($updateTimeAll === null || $updateTime < $updateTimeAll)) { |
| 331 | + if ($updateTime !== null && ($updateTimeAll === null || $updateTime > $updateTimeAll)) { |
330 | 332 | $updateTimeAll = $updateTime; |
331 | 333 | } |
332 | 334 | } |
333 | 335 |
|
334 | 336 | $checkTime = null; |
335 | 337 | if ($this->config->config->ShowDbStructureLastCheck && isset($currentTable['Check_time'])) { |
336 | 338 | $checkTime = $this->createDateTime($currentTable['Check_time']); |
337 | | - if ($checkTime !== null && ($checkTimeAll === null || $checkTime < $checkTimeAll)) { |
| 339 | + if ($checkTime !== null && ($checkTimeAll === null || $checkTime > $checkTimeAll)) { |
338 | 340 | $checkTimeAll = $checkTime; |
339 | 341 | } |
340 | 342 | } |
@@ -859,35 +861,45 @@ private function getValuesForCsvTable(array $currentTable, int $sumSize): array |
859 | 861 | ->countRecords(true); |
860 | 862 |
|
861 | 863 | if ($this->isShowStats) { |
862 | | - // Only count columns that have double quotes |
863 | | - $columnCount = (int) $this->dbi->fetchValue( |
864 | | - 'SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ' |
865 | | - . $this->dbi->quoteString(Current::$database) . ' AND TABLE_NAME = ' |
866 | | - . $this->dbi->quoteString($currentTable['TABLE_NAME']) . ' AND NUMERIC_SCALE IS NULL;', |
867 | | - ); |
868 | | - |
869 | 864 | // Get column names |
870 | | - $columnNames = $this->dbi->fetchValue( |
871 | | - 'SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ' |
| 865 | + /** @var list<array{COLUMN_NAME: string, HAS_QUOTES: numeric-string}> $columns */ |
| 866 | + $columns = $this->dbi->fetchValue( |
| 867 | + 'SELECT COLUMN_NAME, NUMERIC_SCALE IS NULL AS HAS_QUOTES' |
| 868 | + . ' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ' |
872 | 869 | . $this->dbi->quoteString(Current::$database) . ' AND TABLE_NAME = ' |
873 | 870 | . $this->dbi->quoteString($currentTable['TABLE_NAME']) . ';', |
874 | 871 | ); |
875 | 872 |
|
876 | | - // 10Mb buffer for CONCAT_WS |
877 | | - // not sure if is needed |
| 873 | + $columnsString = implode(',', array_map( |
| 874 | + static function (array $column): string { |
| 875 | + return Util::backquote($column['COLUMN_NAME']); |
| 876 | + }, |
| 877 | + $columns, |
| 878 | + )); |
| 879 | + |
| 880 | + // 10Mb buffer for CONCAT not sure if is needed |
878 | 881 | $this->dbi->query('SET SESSION group_concat_max_len = 10 * 1024 * 1024'); |
879 | 882 |
|
880 | 883 | // Calculate data length |
| 884 | + // literal new line, double quote and backslash characters are escaped in csv |
| 885 | + // and use up two bytes instead of one. |
881 | 886 | $dataLength = (int) $this->dbi->fetchValue(' |
882 | | - SELECT SUM(CHAR_LENGTH(REPLACE(REPLACE(REPLACE( |
883 | | - CONCAT_WS(\',\', ' . $columnNames . '), |
884 | | - UNHEX(\'0A\'), \'nn\'), UNHEX(\'22\'), \'nn\'), UNHEX(\'5C\'), \'nn\' |
885 | | - ))) FROM ' . Util::backquote(Current::$database) . '.' . Util::backquote($currentTable['TABLE_NAME'])); |
| 887 | + SELECT SUM(LENGTH(REPLACE( |
| 888 | + REPLACE( |
| 889 | + REPLACE(CONCAT(' . $columnsString . "), '\\n', 'nl'), |
| 890 | + '\"', |
| 891 | + 'qu' |
| 892 | + ), |
| 893 | + '\\\\', |
| 894 | + 'bs' |
| 895 | + ))) FROM " . Util::backquote(Current::$database) . '.' . Util::backquote($currentTable['TABLE_NAME'])); |
886 | 896 |
|
887 | | - // Calculate quotes length |
888 | | - $quotesLength = $currentTable['TABLE_ROWS'] * $columnCount * 2; |
| 897 | + $quotedColumns = array_reduce($columns, static function (int $sum, array $column): int { |
| 898 | + return $sum + (int) $column['HAS_QUOTES']; |
| 899 | + }, 0); |
| 900 | + $separatorsAndNewLine = count($columns); |
889 | 901 |
|
890 | | - $tblsize = $dataLength + $quotesLength + $currentTable['TABLE_ROWS']; |
| 902 | + $tblsize = $dataLength + $currentTable['TABLE_ROWS'] * ($quotedColumns * 2 + $separatorsAndNewLine); |
891 | 903 |
|
892 | 904 | $sumSize += $tblsize; |
893 | 905 | [$formattedSize, $unit] = Util::formatByteDown($tblsize, 3, $tblsize > 0 ? 1 : 0); |
|
0 commit comments