Skip to content

Commit 945efef

Browse files
Merge pull request #19047 from kamil-tekiela/Refactor-import-7
Add AnalysedColumn DTO
2 parents 2016c81 + 0472660 commit 945efef

5 files changed

Lines changed: 71 additions & 71 deletions

File tree

‎phpstan-baseline.neon‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11497,7 +11497,7 @@ parameters:
1149711497

1149811498
-
1149911499
message: "#^Cannot access offset 0 on mixed\\.$#"
11500-
count: 3
11500+
count: 2
1150111501
path: src/Plugins/Import/ImportShp.php
1150211502

1150311503
-

‎psalm-baseline.xml‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8789,9 +8789,6 @@
87898789
<DeprecatedMethod>
87908790
<code><![CDATA[Config::getInstance()]]></code>
87918791
</DeprecatedMethod>
8792-
<InvalidArgument>
8793-
<code><![CDATA[[$analysis]]]></code>
8794-
</InvalidArgument>
87958792
<InvalidArrayOffset>
87968793
<code><![CDATA[$GLOBALS['buffer']]]></code>
87978794
<code><![CDATA[$GLOBALS['eof']]]></code>

‎src/Import/AnalysedColumn.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\Import;
6+
7+
final class AnalysedColumn
8+
{
9+
public function __construct(
10+
public ColumnType $type,
11+
public int|DecimalSize $size,
12+
public bool $isFullyFormattedSql = false,
13+
) {
14+
}
15+
}

‎src/Import/Import.php‎

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
use function __;
2727
use function abs;
28-
use function array_fill;
2928
use function array_key_last;
3029
use function array_map;
3130
use function count;
@@ -60,11 +59,6 @@
6059
*/
6160
class Import
6261
{
63-
/* Analysis array defs */
64-
public const TYPES = 0;
65-
public const SIZES = 1;
66-
public const FORMATTEDSQL = 2;
67-
6862
private string|null $importRunBuffer = null;
6963

7064
public function __construct()
@@ -654,29 +648,33 @@ public function detectType(ColumnType|null $lastCumulativeType, string|null $cel
654648
*
655649
* @link https://wiki.phpmyadmin.net/pma/Import
656650
*
657-
* @return array{ColumnType[], (int|DecimalSize)[]} array(array $types, array $sizes)
651+
* @return AnalysedColumn[]
658652
*/
659653
public function analyzeTable(ImportTable $table): array
660654
{
661655
/* Get number of rows in table */
662656
/* Get number of columns */
663-
$numCols = count($table->columns);
664-
665-
/* Initialize $sizes to all 0's */
666-
$sizes = array_fill(0, $numCols, 0);
657+
$numberOfColumns = count($table->columns);
667658

668-
/* Initialize $types to NONE */
669-
$types = array_fill(0, $numCols, ColumnType::None);
659+
$columns = [];
660+
for ($i = 0; $i < $numberOfColumns; ++$i) {
661+
$columns[] = new AnalysedColumn(ColumnType::None, 0);
662+
}
670663

671664
/* Analyze each column */
672-
for ($i = 0; $i < $numCols; ++$i) {
665+
for ($i = 0; $i < $numberOfColumns; ++$i) {
673666
/* Analyze the column in each row */
674667
foreach ($table->rows as $row) {
675668
$cellValue = $row[$i];
676669
/* Determine type of the current cell */
677-
$currType = $this->detectType($types[$i], $cellValue === null ? null : (string) $cellValue);
670+
$currType = $this->detectType($columns[$i]->type, $cellValue === null ? null : (string) $cellValue);
678671
/* Determine size of the current cell */
679-
$sizes[$i] = $this->detectSize($sizes[$i], $types[$i], $currType, (string) $cellValue);
672+
$columns[$i]->size = $this->detectSize(
673+
$columns[$i]->size,
674+
$columns[$i]->type,
675+
$currType,
676+
(string) $cellValue,
677+
);
680678

681679
/**
682680
* If a type for this column has already been declared,
@@ -687,39 +685,38 @@ public function analyzeTable(ImportTable $table): array
687685
}
688686

689687
if ($currType === ColumnType::Varchar) {
690-
$types[$i] = ColumnType::Varchar;
688+
$columns[$i]->type = ColumnType::Varchar;
691689
} elseif ($currType === ColumnType::Decimal) {
692-
if ($types[$i] !== ColumnType::Varchar) {
693-
$types[$i] = ColumnType::Decimal;
690+
if ($columns[$i]->type !== ColumnType::Varchar) {
691+
$columns[$i]->type = ColumnType::Decimal;
694692
}
695693
} elseif ($currType === ColumnType::BigInt) {
696-
if ($types[$i] !== ColumnType::Varchar && $types[$i] !== ColumnType::Decimal) {
697-
$types[$i] = ColumnType::BigInt;
694+
if ($columns[$i]->type !== ColumnType::Varchar && $columns[$i]->type !== ColumnType::Decimal) {
695+
$columns[$i]->type = ColumnType::BigInt;
698696
}
699697
} elseif ($currType === ColumnType::Int) {
700698
if (
701-
$types[$i] !== ColumnType::Varchar
702-
&& $types[$i] !== ColumnType::Decimal
703-
&& $types[$i] !== ColumnType::BigInt
699+
$columns[$i]->type !== ColumnType::Varchar
700+
&& $columns[$i]->type !== ColumnType::Decimal
701+
&& $columns[$i]->type !== ColumnType::BigInt
704702
) {
705-
$types[$i] = ColumnType::Int;
703+
$columns[$i]->type = ColumnType::Int;
706704
}
707705
}
708706
}
709707
}
710708

711709
/* Check to ensure that all types are valid */
712-
$len = count($types);
713-
for ($n = 0; $n < $len; ++$n) {
714-
if ($types[$n] !== ColumnType::None) {
710+
foreach ($columns as $column) {
711+
if ($column->type !== ColumnType::None) {
715712
continue;
716713
}
717714

718-
$types[$n] = ColumnType::Varchar;
719-
$sizes[$n] = 10;
715+
$column->type = ColumnType::Varchar;
716+
$column->size = 10;
720717
}
721718

722-
return [$types, $sizes];
719+
return $columns;
723720
}
724721

725722
/**
@@ -728,11 +725,10 @@ public function analyzeTable(ImportTable $table): array
728725
*
729726
* @link https://wiki.phpmyadmin.net/pma/Import
730727
*
731-
* @param ImportTable[] $tables
732-
* @param array{0:ColumnType[], 1:(int|DecimalSize)[], 2?:true[]}[]|null $analyses Analyses of the tables
733-
* @param string[]|null $additionalSql Additional SQL
734-
* to be executed
735-
* @param string[] $sqlData List of SQL to be executed
728+
* @param ImportTable[] $tables
729+
* @param AnalysedColumn[][]|null $analyses Analyses of the tables
730+
* @param string[]|null $additionalSql Additional SQL to be executed
731+
* @param string[] $sqlData List of SQL to be executed
736732
*/
737733
public function buildSql(
738734
string $dbName,
@@ -783,20 +779,20 @@ public function buildSql(
783779
. Util::backquote($dbName)
784780
. '.' . Util::backquote($table->tableName) . ' (';
785781
foreach ($table->columns as $j => $column) {
786-
$size = $analyses[$i][self::SIZES][$j];
782+
$size = $analyses[$i][$j]->size;
787783
if ($size === 0) {
788784
$size = 10;
789785
}
790786

791-
$tempSQLStr .= Util::backquote($column) . ' ' . match ($analyses[$i][self::TYPES][$j]) {
787+
$tempSQLStr .= Util::backquote($column) . ' ' . match ($analyses[$i][$j]->type) {
792788
ColumnType::None => 'NULL',
793789
ColumnType::Varchar => 'varchar',
794790
ColumnType::Int => 'int',
795791
ColumnType::Decimal => 'decimal',
796792
ColumnType::BigInt => 'bigint',
797793
ColumnType::Geometry => 'geometry',
798794
};
799-
if ($analyses[$i][self::TYPES][$j] !== ColumnType::Geometry) {
795+
if ($analyses[$i][$j]->type !== ColumnType::Geometry) {
800796
$tempSQLStr .= '(' . $size . ')';
801797
}
802798

@@ -823,9 +819,8 @@ public function buildSql(
823819
*
824820
* Only one insert query is formed for each table
825821
*/
826-
$colCount = 0;
827822
$dbi = DatabaseInterface::getInstance();
828-
foreach ($tables as $i => $table) {
823+
foreach ($tables as $tableIndex => $table) {
829824
$numCols = count($table->columns);
830825
$lastColumnKey = array_key_last($table->columns);
831826

@@ -841,57 +836,49 @@ public function buildSql(
841836
$tempSQLStr .= ') VALUES ';
842837

843838
$lastRowKey = array_key_last($table->rows);
844-
foreach ($table->rows as $j => $row) {
839+
foreach ($table->rows as $rowIndex => $row) {
845840
$tempSQLStr .= '(';
846841

847-
for ($k = 0; $k < $numCols; ++$k) {
842+
for ($columnIndex = 0; $columnIndex < $numCols; ++$columnIndex) {
848843
// If fully formatted SQL, no need to enclose
849844
// with apostrophes, add slashes etc.
850845
if (
851846
$analyses !== null
852-
&& isset($analyses[$i][self::FORMATTEDSQL][$colCount])
847+
&& $analyses[$tableIndex][$columnIndex]->isFullyFormattedSql
853848
) {
854-
$tempSQLStr .= (string) $row[$k];
849+
$tempSQLStr .= (string) $row[$columnIndex];
855850
} else {
856851
if ($analyses !== null) {
857-
$isVarchar = $analyses[$i][self::TYPES][$colCount] === ColumnType::Varchar;
852+
$isVarchar = $analyses[$tableIndex][$columnIndex]->type === ColumnType::Varchar;
858853
} else {
859-
$isVarchar = ! is_numeric($row[$k]);
854+
$isVarchar = ! is_numeric($row[$columnIndex]);
860855
}
861856

862857
/* Don't put quotes around NULL fields */
863-
if ((string) $row[$k] === 'NULL') {
858+
if ((string) $row[$columnIndex] === 'NULL') {
864859
$isVarchar = false;
865860
}
866861

867862
$tempSQLStr .= $isVarchar
868-
? $dbi->quoteString((string) $row[$k])
869-
: (string) $row[$k];
863+
? $dbi->quoteString((string) $row[$columnIndex])
864+
: (string) $row[$columnIndex];
870865
}
871866

872-
if ($k !== $lastColumnKey) {
873-
$tempSQLStr .= ', ';
874-
}
875-
876-
if ($colCount === $lastColumnKey) {
877-
$colCount = 0;
878-
} else {
879-
$colCount++;
867+
if ($columnIndex === $lastColumnKey) {
868+
continue;
880869
}
881870

882-
/* Delete the cell after we are done with it */
883-
unset($table->rows[$j][$k]);
871+
$tempSQLStr .= ', ';
884872
}
885873

886874
$tempSQLStr .= ')';
887875

888-
if ($j !== $lastRowKey) {
876+
if ($rowIndex !== $lastRowKey) {
889877
$tempSQLStr .= ",\n ";
890878
}
891879

892-
$colCount = 0;
893880
/* Delete the row after we are done with it */
894-
unset($table->rows[$j]);
881+
unset($table->rows[$rowIndex]);
895882
}
896883

897884
/**

‎src/Plugins/Import/ImportShp.php‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ public function doImport(File|null $importHandle = null): array
224224
if ($gisObj == null || ! method_exists($gisObj, 'getShape')) {
225225
$tempRow[] = null;
226226
} else {
227-
$tempRow[] = "GeomFromText('"
228-
. $gisObj->getShape($record->shpData) . "')";
227+
$tempRow[] = "GeomFromText('" . $gisObj->getShape($record->shpData) . "')";
229228
}
230229

231230
if ($shp->getDBFHeader() !== null) {
@@ -279,8 +278,10 @@ public function doImport(File|null $importHandle = null): array
279278
// Use data from shape file to chose best-fit MySQL types for each column
280279
$analysis = $this->import->analyzeTable($table);
281280

282-
$analysis[Import::TYPES][0] = ColumnType::Geometry;
283-
$analysis[Import::FORMATTEDSQL][0] = true;
281+
// The first column is the SPATIAL column defined earlier
282+
// This column contains SQL functions and should not be formatted by buildSql()
283+
$analysis[0]->type = ColumnType::Geometry;
284+
$analysis[0]->isFullyFormattedSql = true;
284285

285286
// Set database name to the currently selected one, if applicable
286287
$dbName = Current::$database !== '' ? Current::$database : 'SHP_DB';

0 commit comments

Comments
 (0)