Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/Util/TableFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function getTablesToBake(CollectionInterface $collection, array $options
return $tables;
}

if ($options['require-table'] === true || $options['plugin']) {
if ($options['require-table'] === true) {
$tableNamesInPlugin = $this->getTableNames($options['plugin']);

if (!$tableNamesInPlugin) {
Expand Down
28 changes: 28 additions & 0 deletions tests/TestCase/Command/BakeMigrationSnapshotCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,34 @@ public function testPluginBlog()
$this->runSnapshotTest('PluginBlog', '-p TestBlog');
}

/**
* Test baking a snapshot for a plugin with custom connection (issue #463).
* This tests that when using both --plugin and --connection options,
* the migration includes all tables from the connection, not just those
* with Table classes in the plugin.
*
* @return void
*/
public function testPluginWithCustomConnection()
{
$this->loadPlugins(['SimpleSnapshot']);
$this->migrationPath = ROOT . DS . 'Plugin' . DS . 'SimpleSnapshot' . DS . 'config' . DS . 'Migrations' . DS;

$bakeName = $this->getBakeName('TestSnapshotPluginCustomConnection');
$this->exec("bake migration_snapshot {$bakeName} -c test -p SimpleSnapshot");

$generatedMigration = glob($this->migrationPath . '*_TestSnapshotPluginCustomConnection*.php');
$this->generatedFiles = $generatedMigration;
$this->generatedFiles[] = $this->migrationPath . 'schema-dump-test.lock';

$this->assertNotEmpty($generatedMigration, 'Migration file should be generated');

$content = file_get_contents($generatedMigration[0]);
$this->assertStringContainsString('function up()', $content);
$this->assertStringNotContainsString('public function up(): void {}', $content, 'up() method should not be empty');
$this->assertStringContainsString('->create()', $content, 'Migration should contain table creation statements');
}

protected function runSnapshotTest(string $scenario, string $arguments = ''): void
{
if ($arguments) {
Expand Down
237 changes: 237 additions & 0 deletions tests/comparisons/Migration/pgsql/test_snapshot_plugin_blog_pgsql.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,57 @@ public function up(): void
)
->create();

$this->table('composite_pks', ['id' => false, 'primary_key' => ['id', 'name']])
->addColumn('id', 'uuid', [
'default' => 'a4950df3-515f-474c-be4c-6a027c1957e7',
'limit' => null,
'null' => false,
])
->addColumn('name', 'string', [
'default' => '',
'limit' => 10,
'null' => false,
])
->create();

$this->table('events')
->addColumn('title', 'string', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('description', 'text', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('published', 'string', [
'default' => 'N',
'limit' => 1,
'null' => true,
])
->create();

$this->table('orders')
->addColumn('product_category', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
])
->addColumn('product_id', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
])
->addIndex(
$this->index([
'product_category',
'product_id',
])
->setName('orders_product_category_idx')
)
->create();

$this->table('parts')
->addColumn('name', 'string', [
'default' => null,
Expand All @@ -117,6 +168,143 @@ public function up(): void
])
->create();

$this->table('products')
->addColumn('title', 'string', [
'default' => null,
'limit' => 255,
'null' => true,
])
->addColumn('slug', 'string', [
'default' => null,
'limit' => 100,
'null' => true,
])
->addColumn('category_id', 'integer', [
'default' => null,
'limit' => 10,
'null' => true,
])
->addColumn('created', 'timestamp', [
'default' => null,
'limit' => null,
'null' => true,
'precision' => 6,
'scale' => 6,
])
->addColumn('modified', 'timestamp', [
'default' => null,
'limit' => null,
'null' => true,
'precision' => 6,
'scale' => 6,
])
->addIndex(
$this->index([
'id',
'category_id',
])
->setName('products_category_unique')
->setType('unique')
)
->addIndex(
$this->index('slug')
->setName('products_slug_unique')
->setType('unique')
)
->addIndex(
$this->index('title')
->setName('products_title_idx')
)
->create();

$this->table('special_pks', ['id' => false, 'primary_key' => ['id']])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the expected behavior now? Generating a migration for a plugin without --require-table will include every table in the database?

Copy link
Member Author

@dereuromark dereuromark Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the initial report. I think it does make sense as outlined above, since otherwise you couldnt use it for plugins initially at all.

->addColumn('id', 'uuid', [
'default' => 'a4950df3-515f-474c-be4c-6a027c1957e7',
'limit' => null,
'null' => false,
])
->addColumn('name', 'string', [
'default' => null,
'limit' => 256,
'null' => true,
])
->create();

$this->table('special_tags')
->addColumn('article_id', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
])
->addColumn('author_id', 'integer', [
'default' => null,
'limit' => 10,
'null' => true,
])
->addColumn('tag_id', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
])
->addColumn('highlighted', 'boolean', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('highlighted_time', 'timestamp', [
'default' => null,
'limit' => null,
'null' => true,
'precision' => 6,
'scale' => 6,
])
->addIndex(
$this->index('article_id')
->setName('special_tags_article_unique')
->setType('unique')
)
->create();

$this->table('texts', ['id' => false])
->addColumn('title', 'string', [
'default' => null,
'limit' => null,
'null' => true,
])
->addColumn('description', 'text', [
'default' => null,
'limit' => null,
'null' => true,
])
->create();

$this->table('users')
->addColumn('username', 'string', [
'default' => null,
'limit' => 256,
'null' => true,
])
->addColumn('password', 'string', [
'default' => null,
'limit' => 256,
'null' => true,
])
->addColumn('created', 'timestamp', [
'default' => null,
'limit' => null,
'null' => true,
'precision' => 6,
'scale' => 6,
])
->addColumn('updated', 'timestamp', [
'default' => null,
'limit' => null,
'null' => true,
'precision' => 6,
'scale' => 6,
])
->create();

$this->table('articles')
->addForeignKey(
$this->foreignKey('category_id')
Expand All @@ -127,6 +315,34 @@ public function up(): void
->setName('articles_category_fk')
)
->update();

$this->table('orders')
->addForeignKey(
$this->foreignKey([
'product_category',
'product_id',
])
->setReferencedTable('products')
->setReferencedColumns([
'category_id',
'id',
])
->setOnDelete('CASCADE')
->setOnUpdate('CASCADE')
->setName('orders_product_fk')
)
->update();

$this->table('products')
->addForeignKey(
$this->foreignKey('category_id')
->setReferencedTable('categories')
->setReferencedColumns('id')
->setOnDelete('CASCADE')
->setOnUpdate('CASCADE')
->setName('products_category_fk')
)
->update();
}

/**
Expand All @@ -144,8 +360,29 @@ public function down(): void
'category_id'
)->save();

$this->table('orders')
->dropForeignKey(
[
'product_category',
'product_id',
]
)->save();

$this->table('products')
->dropForeignKey(
'category_id'
)->save();

$this->table('articles')->drop()->save();
$this->table('categories')->drop()->save();
$this->table('composite_pks')->drop()->save();
$this->table('events')->drop()->save();
$this->table('orders')->drop()->save();
$this->table('parts')->drop()->save();
$this->table('products')->drop()->save();
$this->table('special_pks')->drop()->save();
$this->table('special_tags')->drop()->save();
$this->table('texts')->drop()->save();
$this->table('users')->drop()->save();
}
}
Loading
Loading