Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BaseMigration::index() #792

Merged
merged 4 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading