Skip to content

Commit

Permalink
Automatically quoting all identifiers if database platform is passed …
Browse files Browse the repository at this point in the history
…to the naming strategy (warning: BC break on naming strategy)
  • Loading branch information
moufmouf committed Sep 4, 2017
1 parent 6fb5fb3 commit 3c6b943
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 13 deletions.
21 changes: 21 additions & 0 deletions README.md
Expand Up @@ -200,3 +200,24 @@ $db->table('users')
```

The `extends` method will automatically create a primary key with the same name and same type as the extended table. It will also make sure this primary key is a foreign key pointing to the extended table.

## Automatic 'quoting' of table and column names

By default, the fluid-schema-builder will **not** quote your identifiers (because it does not know what database you use).

This means that you cannot create an item with a reserved keyword.

```php
$db->table('contacts')
->id()
->column('date')->datetime(); // Will most likely fail, because "date" is a reserved keyword!
```

However, if you give to *fluid-schema-builder* your database platform at build time, then it **will quote all identifiers by default**. No more nasty surprises!

```php
use TheCodingMachine\FluidSchema\DefaultNamingStrategy;

// Assuming $connection is your DBAL connection
$db = new FluidSchema($schema, new DefaultNamingStrategy($connection->getDatabasePlatform()));
```
22 changes: 22 additions & 0 deletions src/DefaultNamingStrategy.php
Expand Up @@ -4,9 +4,20 @@
namespace TheCodingMachine\FluidSchema;

use Doctrine\Common\Inflector\Inflector;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class DefaultNamingStrategy implements NamingStrategyInterface
{
/**
* @var AbstractPlatform
*/
private $platform;

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

/**
* Returns the name of the jointure table from the name of the joined tables.
*
Expand Down Expand Up @@ -48,4 +59,15 @@ private function toSingular($plural): string

return implode('_', $strs);
}

/**
* Let's quote if a database platform has been provided to us!
*
* @param string $identifier
* @return string
*/
public function quoteIdentifier(string $identifier): string
{
return ($this->platform !== null) ? $this->platform->quoteIdentifier($identifier) : $identifier;
}
}
15 changes: 11 additions & 4 deletions src/FluidColumn.php
Expand Up @@ -25,6 +25,10 @@ class FluidColumn
* @var Table
*/
private $table;
/**
* @var NamingStrategyInterface
*/
private $namingStrategy;

/**
* FluidColumn constructor.
Expand All @@ -33,12 +37,13 @@ class FluidColumn
* @param Table $table
* @param Column $column
*/
public function __construct(FluidSchema $fluidSchema, FluidTable $fluidTable, Table $table, Column $column)
public function __construct(FluidSchema $fluidSchema, FluidTable $fluidTable, Table $table, Column $column, NamingStrategyInterface $namingStrategy)
{
$this->fluidSchema = $fluidSchema;
$this->fluidTable = $fluidTable;
$this->column = $column;
$this->table = $table;
$this->namingStrategy = $namingStrategy;
}

public function integer(): FluidColumnOptions
Expand Down Expand Up @@ -208,6 +213,8 @@ public function object(): FluidColumnOptions

public function references(string $tableName, ?string $constraintName = null, string $onUpdate = 'RESTRICT', string $onDelete = 'RESTRICT'): FluidColumnOptions
{
$tableName = $this->namingStrategy->quoteIdentifier($tableName);

$table = $this->fluidSchema->getDbalSchema()->getTable($tableName);

$referencedColumns = $table->getPrimaryKeyColumns();
Expand All @@ -216,7 +223,7 @@ public function references(string $tableName, ?string $constraintName = null, st
throw new FluidSchemaException('You cannot reference a table with a primary key on several columns using FluidSchema. Use DBAL Schema methods instead.');
}

$referencedColumnName = $referencedColumns[0];
$referencedColumnName = $this->namingStrategy->quoteIdentifier($referencedColumns[0]);
$referencedColumn = $table->getColumn($referencedColumnName);

$this->column->setType($referencedColumn->getType());
Expand All @@ -226,7 +233,7 @@ public function references(string $tableName, ?string $constraintName = null, st
$this->column->setPrecision($referencedColumn->getPrecision());
$this->column->setUnsigned($referencedColumn->getUnsigned());

$this->table->addForeignKeyConstraint($table, [$this->column->getName()], $referencedColumns, [
$this->table->addForeignKeyConstraint($table, [$this->namingStrategy->quoteIdentifier($this->column->getName())], $referencedColumns, [
'onUpdate' => $onUpdate,
'onDelete' => $onDelete
], $constraintName);
Expand All @@ -235,6 +242,6 @@ public function references(string $tableName, ?string $constraintName = null, st

private function getOptions(): FluidColumnOptions
{
return new FluidColumnOptions($this->fluidTable, $this->column);
return new FluidColumnOptions($this->fluidTable, $this->column, $this->namingStrategy);
}
}
11 changes: 8 additions & 3 deletions src/FluidColumnOptions.php
Expand Up @@ -16,16 +16,21 @@ class FluidColumnOptions
* @var Column
*/
private $column;
/**
* @var NamingStrategyInterface
*/
private $namingStrategy;

/**
* FluidColumn constructor.
* @param FluidTable $fluidTable
* @param Column $column
*/
public function __construct(FluidTable $fluidTable, Column $column)
public function __construct(FluidTable $fluidTable, Column $column, NamingStrategyInterface $namingStrategy)
{
$this->fluidTable = $fluidTable;
$this->column = $column;
$this->namingStrategy = $namingStrategy;
}

/**
Expand Down Expand Up @@ -66,7 +71,7 @@ public function unique(): FluidColumnOptions
*/
public function index(): FluidColumnOptions
{
$this->fluidTable->index([$this->column->getName()]);
$this->fluidTable->index([$this->namingStrategy->quoteIdentifier($this->column->getName())]);
return $this;
}
public function comment(string $comment): FluidColumnOptions
Expand All @@ -85,7 +90,7 @@ public function primaryKey(?string $indexName = null): FluidColumnOptions
{
$newIndexName = $indexName ?: false;

$this->fluidTable->primaryKey([$this->column->getName()], $newIndexName);
$this->fluidTable->primaryKey([$this->namingStrategy->quoteIdentifier($this->column->getName())], $newIndexName);
return $this;
}

Expand Down
4 changes: 3 additions & 1 deletion src/FluidSchema.php
Expand Up @@ -34,6 +34,8 @@ public function __construct(Schema $schema, ?NamingStrategyInterface $namingStra

public function table(string $name): FluidTable
{
$name = $this->namingStrategy->quoteIdentifier($name);

if (isset($this->fluidTables[$name])) {
return $this->fluidTables[$name];
}
Expand All @@ -44,7 +46,7 @@ public function table(string $name): FluidTable
$table = $this->schema->createTable($name);
}

$this->fluidTables[$name] = new FluidTable($this, $table);
$this->fluidTables[$name] = new FluidTable($this, $table, $this->namingStrategy);
return $this->fluidTables[$name];
}

Expand Down
24 changes: 19 additions & 5 deletions src/FluidTable.php
Expand Up @@ -19,19 +19,26 @@ class FluidTable
* @var FluidColumn[]
*/
private $fluidColumns;
/**
* @var NamingStrategyInterface
*/
private $namingStrategy;

/**
* @param FluidSchema $schema
* @param Table $table
*/
public function __construct(FluidSchema $schema, Table $table)
public function __construct(FluidSchema $schema, Table $table, NamingStrategyInterface $namingStrategy)
{
$this->schema = $schema;
$this->table = $table;
$this->namingStrategy = $namingStrategy;
}

public function column(string $name): FluidColumn
{
$name = $this->namingStrategy->quoteIdentifier($name);

if (isset($this->fluidColumns[$name])) {
return $this->fluidColumns[$name];
}
Expand All @@ -42,30 +49,35 @@ public function column(string $name): FluidColumn
$column = $this->table->addColumn($name, 'string');
}

$this->fluidColumns[$name] = new FluidColumn($this->schema, $this, $this->table, $column);
$this->fluidColumns[$name] = new FluidColumn($this->schema, $this, $this->table, $column, $this->namingStrategy);
return $this->fluidColumns[$name];
}

public function index(array $columnNames): FluidTable
{
$this->table->addIndex($columnNames);
$this->table->addIndex($this->quoteArray($columnNames));
return $this;
}

public function unique(array $columnNames): FluidTable
{
$this->table->addUniqueIndex($columnNames);
$this->table->addUniqueIndex($this->quoteArray($columnNames));
return $this;
}

public function primaryKey(array $columnNames, ?string $indexName = null): FluidTable
{
$newIndexName = $indexName ?: false;

$this->table->setPrimaryKey($columnNames, $newIndexName);
$this->table->setPrimaryKey($this->quoteArray($columnNames), $newIndexName);
return $this;
}

private function quoteArray(array $columnNames): array
{
return array_map([$this->namingStrategy, 'quoteIdentifier'], $columnNames);
}

/**
* Creates a "id" autoincremented primary key column.
*
Expand Down Expand Up @@ -102,6 +114,8 @@ public function timestamps(): FluidTable

public function extends(string $tableName): FluidTable
{
$tableName = $this->namingStrategy->quoteIdentifier($tableName);

$inheritedTable = $this->schema->getDbalSchema()->getTable($tableName);

$pks = $inheritedTable->getPrimaryKeyColumns();
Expand Down
8 changes: 8 additions & 0 deletions src/NamingStrategyInterface.php
Expand Up @@ -20,4 +20,12 @@ public function getJointureTableName(string $table1, string $table2): string;
* @return string
*/
public function getForeignKeyColumnName(string $targetTable): string;

/**
* Decides to quote an identifier (or not) and returns the result.
*
* @param string $identifier
* @return string
*/
public function quoteIdentifier(string $identifier): string;
}

0 comments on commit 3c6b943

Please sign in to comment.