Skip to content

Commit

Permalink
Merge pull request #792 from cakephp/index-fluent
Browse files Browse the repository at this point in the history
Add BaseMigration::index()
  • Loading branch information
markstory authored Dec 26, 2024
2 parents f86a231 + 0a4320a commit f827342
Show file tree
Hide file tree
Showing 23 changed files with 319 additions and 535 deletions.
12 changes: 12 additions & 0 deletions src/BaseMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Migrations\Db\Adapter\AdapterInterface;
use Migrations\Db\Table;
use Migrations\Db\Table\ForeignKey;
use Migrations\Db\Table\Index;
use RuntimeException;

/**
Expand Down Expand Up @@ -436,6 +437,17 @@ public function foreignKey(string|array $columns): ForeignKey
return (new ForeignKey())->setColumns($columns);
}

/**
* Create a new Index object.
*
* @params string|string[] $columns Columns
* @return \Migrations\Db\Table\Index
*/
public function index(string|array $columns): Index
{
return (new Index())->setColumns($columns);
}

/**
* Perform checks on the migration, printing a warning
* if there are potential problems.
Expand Down
1 change: 1 addition & 0 deletions src/Db/Adapter/PostgresAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,7 @@ protected function getIndexSqlDefinition(Index $index, string $tableName): strin
$include = $index->getInclude();
$includedColumns = $include ? sprintf('INCLUDE ("%s")', implode('","', $include)) : '';

// TODO always concurrently
$createIndexSentence = 'CREATE %s INDEX %s ON %s ';
if ($index->getType() === self::GIN_INDEX_TYPE) {
$createIndexSentence .= ' USING ' . $index->getType() . '(%s) %s;';
Expand Down
8 changes: 8 additions & 0 deletions src/Db/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Migrations\Db\Table\Index;
use Migrations\Db\Table\Table as TableValue;
use RuntimeException;
use function Cake\Core\deprecationWarning;

/**
* This object is based loosely on: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html.
Expand Down Expand Up @@ -513,6 +514,8 @@ public function addForeignKey(string|array|ForeignKey $columns, string|TableValu
* @param string|string[] $referencedColumns Referenced Columns
* @param array<string, mixed> $options Options
* @return $this
* @deprecated 4.6.0 Use addForeignKey() instead. Use `BaseMigration::foreignKey()` to get
* a fluent interface for building foreign keys.
*/
public function addForeignKeyWithName(
string|ForeignKey $name,
Expand All @@ -521,6 +524,11 @@ public function addForeignKeyWithName(
string|array $referencedColumns = ['id'],
array $options = []
) {
deprecationWarning(
'4.6.0',
'Use addForeignKey() instead. Use `BaseMigration::foreignKey()` to get a fluent' .
' interface for building foreign keys.'
);
if (is_string($name)) {
if ($columns === null || $referencedTable === null) {
throw new InvalidArgumentException(
Expand Down
2 changes: 1 addition & 1 deletion src/Db/Table/ForeignKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* Used to define foreign keys that are added to tables as part of migrations.
*
* @see \Migrations\Db\Table::foreignKey()
* @see \Migrations\BaseMigration::foreignKey()
* @see \Migrations\Db\Table::addForeignKey()
*/
class ForeignKey
Expand Down
23 changes: 22 additions & 1 deletion src/Db/Table/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@

use RuntimeException;

/**
* Index value object
*
* Used to define indexes that are added to tables as part of migrations.
*
* @see \Migrations\BaseMigration::index()
* @see \Migrations\Db\Table::addIndex()
*
* TODO expand functionality of Index:
* - Add ifnotexists
* - Add nullsfirst/nullslast
* - Add where for partial indexes
*/
class Index
{
/**
Expand Down Expand Up @@ -129,6 +142,9 @@ public function getName(): ?string
/**
* Sets the index limit.
*
* In MySQL indexes can have limit clauses to control the number of
* characters indexed in text and char columns.
*
* @param int|array $limit limit value or array of limit value
* @return $this
*/
Expand Down Expand Up @@ -173,7 +189,12 @@ public function getOrder(): ?array
}

/**
* Sets the index included columns.
* Sets the index included columns for a 'covering index'.
*
* In postgres and sqlserver, indexes can define additional non-key
* columns to build 'covering indexes'. This feature allows you to
* further optimize well-crafted queries that leverage specific
* indexes by reading all data from the index.
*
* @param string[] $includedColumns Columns
* @return $this
Expand Down
2 changes: 1 addition & 1 deletion templates/bake/config/diff.twig
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ not empty %}
{{ Migration.element('Migrations.add-columns', {'columns': tableDiff['columns']['add']}) | raw -}}
{% endif -%}
{% if tableDiff['indexes']['add'] is not empty %}
{{ Migration.element('Migrations.add-indexes', {'indexes': tableDiff['indexes']['add']}) | raw -}}
{{ Migration.element('Migrations.add-indexes', {'backend': backend, 'indexes': tableDiff['indexes']['add']}) | raw -}}
{% endif -%}
{% if Migration.wasTableStatementGeneratedFor(tableName) %}
->update();
Expand Down
26 changes: 22 additions & 4 deletions templates/bake/element/add-indexes.twig
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
{% for indexName, index in indexes %}
{% set columnsList = '\'' ~ index['columns'][0] ~ '\'' %}
{% if index['columns']|length > 1 %}
{% set columnsList = '[' ~ Migration.stringifyList(index['columns'], {'indent': 6}) ~ ']' %}
{% endif %}
->addIndex(
{% if backend == 'builtin' %}
$this->index({{ columnsList | raw }})
->setName('{{ indexName }}')
{% if index['type'] == 'unique' %}
->setType('unique')
{% elseif index['type'] == 'fulltext' %}
->setType('fulltext')
{% endif %}
{% if index['options'] %}
->setOptions([{{ Migration.stringifyList(index['options'], {'indent': 6}) | raw }}])
{% endif %}
)
{% else %}
[{{ Migration.stringifyList(index['columns'], {'indent': 5}) | raw }}],
{% set params = {'name': indexName} %}
{% if index['type'] == 'unique' %}
{% set params = params|merge({'unique': true}) %}
{% endif %}
{% set params = {'name': indexName} %}
{% if index['type'] == 'unique' %}
{% set params = params|merge({'unique': true}) %}
{% endif %}
[{{ Migration.stringifyList(params, {'indent': 5}) | raw }}]
)
{% endif %}
{% endfor %}
25 changes: 8 additions & 17 deletions templates/bake/element/create-tables.twig
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,17 @@
{% if createData.tables[table].constraints is not empty %}
{% for name, constraint in createData.tables[table].constraints %}
{% if constraint['type'] == 'unique' %}
->addIndex(
[{{ Migration.stringifyList(constraint['columns'], {'indent': 5}) | raw }}],
{% set params = {'name': name, 'unique': true} %}
[{{ Migration.stringifyList(params, {'indent': 5}) | raw }}]
)
{{ element('Migrations.add-indexes', {
indexes: {(name): constraint},
backend: backend,
}) -}}
{% endif %}
{% endfor %}
{% endif %}
{% for indexName, index in createData.tables[table].indexes %}
{% set indexColumns = index['columns'] | sort %}
->addIndex(
[{{ Migration.stringifyList(index['columns'], {'indent': 5}) | raw }}],
{% set params = {'name': indexName} %}
{% if index['type'] == 'fulltext' %}
{% set params = params|merge({'type': 'fulltext'}) %}
{% endif %}
[{{ Migration.stringifyList(params, {'indent': 5}) | raw }}]
)
{% endfor %}
->create();
{{- element('Migrations.add-indexes', {
indexes: createData.tables[table].indexes,
backend: backend,
}) }} ->create();
{% endfor -%}
{% if createData.constraints %}
{% for table, tableConstraints in createData.constraints %}
Expand Down
66 changes: 17 additions & 49 deletions tests/comparisons/Diff/default/the_diff_default_mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,12 @@ public function up(): void
'signed' => true,
])
->addIndex(
[
'user_id',
],
[
'name' => 'categories_ibfk_1',
]
$this->index('user_id')
->setName('categories_ibfk_1')
)
->addIndex(
[
'name',
],
[
'name' => 'name',
]
$this->index('name')
->setName('name')
)
->create();

Expand Down Expand Up @@ -123,28 +115,16 @@ public function up(): void
'signed' => true,
])
->addIndex(
[
'slug',
],
[
'name' => 'UNIQUE_SLUG',
]
$this->index('slug')
->setName('UNIQUE_SLUG')
)
->addIndex(
[
'category_id',
],
[
'name' => 'category_id',
]
$this->index('category_id')
->setName('category_id')
)
->addIndex(
[
'name',
],
[
'name' => 'rating_index',
]
$this->index('name')
->setName('rating_index')
)
->update();

Expand Down Expand Up @@ -233,29 +213,17 @@ public function down(): void
->removeColumn('category_id')
->removeColumn('average_note')
->addIndex(
[
'slug',
],
[
'name' => 'UNIQUE_SLUG',
'unique' => true,
]
$this->index('slug')
->setName('UNIQUE_SLUG')
->setType('unique')
)
->addIndex(
[
'rating',
],
[
'name' => 'rating_index',
]
$this->index('rating')
->setName('rating_index')
)
->addIndex(
[
'name',
],
[
'name' => 'BY_NAME',
]
$this->index('name')
->setName('BY_NAME')
)
->update();

Expand Down
8 changes: 2 additions & 6 deletions tests/comparisons/Diff/simple/the_diff_simple_mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,8 @@ public function up(): void
'signed' => false,
])
->addIndex(
[
'user_id',
],
[
'name' => 'user_id',
]
$this->index('user_id')
->setName('user_id')
)
->update();

Expand Down
Loading

0 comments on commit f827342

Please sign in to comment.