Skip to content

Commit

Permalink
Use platform for column escaping in bulk insert
Browse files Browse the repository at this point in the history
  • Loading branch information
stloyd committed Nov 28, 2023
1 parent 2f360d6 commit 59ef19d
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 41 deletions.
5 changes: 0 additions & 5 deletions src/lib/doctrine-dbal-bulk/src/Flow/Doctrine/Bulk/Columns.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ public function all() : array
return $this->columns;
}

public function concat(string $separator) : string
{
return \implode($separator, $this->columns);
}

/**
* @param string ...$columnNames
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public function dialect() : Dialect
}

if ($this->isMySQL() || $this->isMariaDB()) {
return new MySQLDialect();
return new MySQLDialect($this->platform);
}

if ($this->isSqlite()) {
return new SqliteDialect();
return new SqliteDialect($this->platform);
}

throw new RuntimeException(\sprintf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@

namespace Flow\Doctrine\Bulk\Dialect;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Flow\Doctrine\Bulk\BulkData;
use Flow\Doctrine\Bulk\Columns;
use Flow\Doctrine\Bulk\Exception\RuntimeException;
use Flow\Doctrine\Bulk\TableDefinition;

final class MySQLDialect implements Dialect
{
public function __construct(private readonly AbstractPlatform $platform)
{
}

/**
* @psalm-suppress MoreSpecificImplementedParamType
*
Expand All @@ -30,7 +35,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON DUPLICATE KEY UPDATE %4$s=%4$s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders(),
\current($bulkData->columns()->all())
);
Expand All @@ -42,7 +47,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
VALUES %s
ON DUPLICATE KEY UPDATE %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders(),
\array_key_exists('update_columns', $insertOptions) && \count($insertOptions['update_columns'])
? $this->updateSelectedColumns($insertOptions['update_columns'], $bulkData->columns())
Expand All @@ -53,7 +58,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}
Expand All @@ -72,7 +77,7 @@ public function prepareUpdate(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'REPLACE INTO %s (%s) VALUES %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}
Expand All @@ -87,7 +92,7 @@ private function updateAllColumns(Columns $columns) : string
return \implode(
',',
$columns->map(
fn (string $column) : string => "{$column} = VALUES({$column})"
fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = VALUES({$this->platform->quoteIdentifier($column)})"
)
);
}
Expand All @@ -101,7 +106,7 @@ private function updateAllColumns(Columns $columns) : string
private function updateSelectedColumns(array $updateColumns, Columns $columns) : string
{
return \count($updateColumns)
? \implode(',', \array_map(fn (string $column) : string => "{$column} = VALUES({$column})", $updateColumns))
? \implode(',', \array_map(fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = VALUES({$this->platform->quoteIdentifier($column)})", $updateColumns))
: $this->updateAllColumns($columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@

final class PostgreSQLDialect implements Dialect
{
private AbstractPlatform $platform;

public function __construct(AbstractPlatform $platform)
public function __construct(private readonly AbstractPlatform $platform)
{
$this->platform = $platform;
}

/**
Expand All @@ -39,7 +36,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON CONFLICT (%s) DO UPDATE SET %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders(),
\implode(',', $insertOptions['conflict_columns']),
(\array_key_exists('update_columns', $insertOptions) && \count($insertOptions['update_columns']))
Expand All @@ -52,7 +49,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON CONFLICT ON CONSTRAINT %s DO UPDATE SET %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders(),
$insertOptions['constraint'],
(\array_key_exists('update_columns', $insertOptions) && \count($insertOptions['update_columns']))
Expand All @@ -65,15 +62,15 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON CONFLICT DO NOTHING',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}

return \sprintf(
'INSERT INTO %s (%s) VALUES %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}
Expand Down Expand Up @@ -109,7 +106,7 @@ public function prepareUpdate(TableDefinition $table, BulkData $bulkData, array
? $this->updatedSelectedColumns($updateOptions['update_columns'], $bulkData->columns()->without(...$updateOptions['primary_key_columns']))
: $this->updateAllColumns($bulkData->columns()->without(...$updateOptions['primary_key_columns'])),
$table->toSqlCastedPlaceholders($bulkData, $this->platform),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$this->updatedIndexColumns($updateOptions['primary_key_columns'])
);
}
Expand All @@ -129,7 +126,7 @@ private function updateAllColumns(Columns $columns) : string
return \implode(
',',
$columns->map(
fn (string $column) : string => "{$column} = excluded.{$column}"
fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = {$this->platform->quoteIdentifier('excluded.' . $column)}"
)
);
}
Expand All @@ -141,7 +138,7 @@ private function updateAllColumns(Columns $columns) : string
*/
private function updatedIndexColumns(array $updateColumns) : string
{
return \implode(' AND ', \array_map(fn (string $column) : string => "existing_table.{$column} = excluded.{$column}", $updateColumns));
return \implode(' AND ', \array_map(fn (string $column) : string => "{$this->platform->quoteIdentifier('existing_table.' . $column)} = {$this->platform->quoteIdentifier('excluded.' . $column)}", $updateColumns));
}

/**
Expand All @@ -158,7 +155,7 @@ private function updatedSelectedColumns(array $updateColumns, Columns $columns)
* table's name (or an alias), and to rows proposed for insertion using the special EXCLUDED table.
*/
return \count($updateColumns)
? \implode(',', \array_map(fn (string $column) : string => "{$column} = excluded.{$column}", $updateColumns))
? \implode(',', \array_map(fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = {$this->platform->quoteIdentifier('excluded.' . $column)}", $updateColumns))
: $this->updateAllColumns($columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

namespace Flow\Doctrine\Bulk\Dialect;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Flow\Doctrine\Bulk\BulkData;
use Flow\Doctrine\Bulk\Columns;
use Flow\Doctrine\Bulk\TableDefinition;

final class SqliteDialect implements Dialect
{
public function __construct(private readonly AbstractPlatform $platform)
{
}

/**
* @psalm-suppress MoreSpecificImplementedParamType
*
Expand All @@ -25,7 +30,7 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON CONFLICT (%s) DO UPDATE SET %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders(),
\implode(',', $insertOptions['conflict_columns']),
(\array_key_exists('update_columns', $insertOptions) && [] !== $insertOptions['update_columns'])
Expand All @@ -38,15 +43,15 @@ public function prepareInsert(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'INSERT INTO %s (%s) VALUES %s ON CONFLICT DO NOTHING',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}

return \sprintf(
'INSERT INTO %s (%s) VALUES %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}
Expand All @@ -56,7 +61,7 @@ public function prepareUpdate(TableDefinition $table, BulkData $bulkData, array
return \sprintf(
'REPLACE INTO %s (%s) VALUES %s',
$table->name(),
$bulkData->columns()->concat(','),
\implode(',', \array_map(fn (string $column) : string => $this->platform->quoteIdentifier($column), $bulkData->columns()->all())),
$bulkData->toSqlPlaceholders()
);
}
Expand All @@ -66,7 +71,7 @@ private function updateAllColumns(Columns $columns) : string
return \implode(
',',
$columns->map(
fn (string $column) : string => "{$column} = excluded.{$column}"
fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = {$this->platform->quoteIdentifier('excluded.' . $column)}"
)
);
}
Expand All @@ -77,7 +82,7 @@ private function updateAllColumns(Columns $columns) : string
private function updateSelectedColumns(array $updateColumns, Columns $columns) : string
{
return [] !== $updateColumns
? \implode(',', \array_map(static fn (string $column) : string => "{$column} = excluded.{$column}", $updateColumns))
? \implode(',', \array_map(fn (string $column) : string => "{$this->platform->quoteIdentifier($column)} = {$this->platform->quoteIdentifier('excluded.' . $column)}", $updateColumns))
: $this->updateAllColumns($columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,4 @@ public function test_transforms_all_columns_to_placeholders() : void
$columns->prefix(':')
);
}

public function test_transforms_columns_to_string_using_comma_as_a_separator() : void
{
$columns = new Columns('date', 'title', 'description', 'quantity');

$this->assertEquals(
'date,title,description,quantity',
$columns->concat(',')
);
}
}

0 comments on commit 59ef19d

Please sign in to comment.