Skip to content
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
88 changes: 57 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
[![Packagist Version](https://img.shields.io/packagist/v/kraz/doctrine-context-bundle)](https://packagist.org/packages/kraz/doctrine-context-bundle)
[![GitHub license](https://img.shields.io/github/license/kraz/doctrine-context-bundle)](LICENSE)

A Symfony bundle that makes working with multiple Doctrine entity managers or DBAL connections painless. It wraps the standard `doctrine/migrations` commands (and optionally ORM schema commands) so that a single command can target one specific context or fan out across all of them automatically.
A Symfony bundle that makes working with multiple Doctrine entity managers or DBAL connections painless. It wraps the standard Doctrine commands so that a single command can target one specific context or fan out across all of them automatically. The only hard dependency is `doctrine/dbal` — ORM and Migrations support are both optional.

## The problem

When a project has more than one entity manager or DBAL connection, running migrations requires repeating the same command once per context, which requires each time specifying the right `--em` or `--conn` flag manually:
When a project has more than one entity manager or DBAL connection, running the same operation across all of them requires repeating the command manually once per context:

```bash
php bin/console doctrine:migrations:migrate --em=shop
Expand All @@ -20,21 +20,20 @@ There is also a subtle schema-pollution problem: after running migrations, `doct

## What this bundle does

- **Context-aware commands**: every `doctrine:migrations:*` command gains `--em` and `--conn` options. Pass one to target a specific context, or omit both to run across all registered contexts in sequence.
- **Database command integration**: `doctrine:database:create` fans out across all registered contexts. Works with DBAL alone — no ORM or Migrations required. Accepts both `--connection` (native option) and `--conn` (context-system alias).
- **Migrations command integration** *(requires `doctrine/doctrine-migrations-bundle`)*: every `doctrine:migrations:*` command gains `--em` and `--conn` options. Pass one to target a specific context, or omit both to run across all registered contexts in sequence.
- **ORM command integration** *(requires `doctrine/orm`)*: `doctrine:schema:create`, `doctrine:schema:validate`, and `doctrine:mapping:info` receive the same fan-out behaviour.
- **Database command integration**: `doctrine:database:create` fans out across all registered contexts. Accepts both `--connection` (native option) and `--conn` (context-system alias).
- **Schema filter**: automatically hides the migration metadata table from `doctrine:schema:update` and `doctrine:schema:validate`, so those commands never see it as unmanaged.
- **`--ctx-isolation`**: an extra flag added to every wrapped command. When set, a failure in one context does not abort the remaining contexts.

## Requirements

| Dependency | Version |
|---------------------------------------|---------------------|
| PHP | `>= 8.4` |
| `doctrine/dbal` | `^4.4` |
| `symfony/console` | `^8.0` |
| `doctrine/doctrine-migrations-bundle` | `^4.0` *(dev)* |
| `doctrine/orm` | `^3.6` *(optional)* |
| Dependency | Version |
|---------------------------------------|----------------------|
| PHP | `>= 8.4` |
| `doctrine/doctrine-bundle` | `^3.2` |
| `doctrine/doctrine-migrations-bundle` | `^4.0` *(optional)* |
| `doctrine/orm` | `^3.6` *(optional)* |

## Installation

Expand All @@ -53,14 +52,26 @@ return [

## Configuration

Register each entity manager or connection that should be treated as a named context. You may use `entity_managers` (requires `doctrine/orm`), `connections`, or a mix, but not both for the same name.
Register each entity manager or connection that should be treated as a named context. You may use `entity_managers` (requires `doctrine/orm`) or `connections`, but not both for the same name.

### With entity managers
The migration-related options (`migrations_paths`, `storage`, `services`, etc.) are only available when `doctrine/doctrine-migrations-bundle` is installed. Without it, a context is configured with just its name.

### DBAL only (no ORM, no Migrations)

```yaml
# config/packages/doctrine_context.yaml
doctrine_context:
entity_managers:
connections:
default: ~
shop: ~
analytics: ~
```

### With DBAL connections and Migrations

```yaml
doctrine_context:
connections:
default:
migrations_paths:
App\Migrations\Default: '%kernel.project_dir%/migrations/default'
Expand All @@ -73,19 +84,13 @@ doctrine_context:
storage:
table_storage:
table_name: doctrine_migration_versions
analytics:
migrations_paths:
App\Migrations\Analytics: '%kernel.project_dir%/migrations/analytics'
storage:
table_storage:
table_name: doctrine_migration_versions
```

### With DBAL connections only
### With entity managers (ORM) and Migrations

```yaml
doctrine_context:
connections:
entity_managers:
default:
migrations_paths:
App\Migrations\Default: '%kernel.project_dir%/migrations/default'
Expand All @@ -95,10 +100,31 @@ doctrine_context:
shop:
migrations_paths:
App\Migrations\Shop: '%kernel.project_dir%/migrations/shop'
storage:
table_storage:
table_name: doctrine_migration_versions
analytics:
migrations_paths:
App\Migrations\Analytics: '%kernel.project_dir%/migrations/analytics'
storage:
table_storage:
table_name: doctrine_migration_versions
```

### With entity managers (ORM), no Migrations

```yaml
doctrine_context:
entity_managers:
default: ~
shop: ~
analytics: ~
```

### Full configuration reference

The migration-related keys below are only accepted when `doctrine/doctrine-migrations-bundle` is installed.

```yaml
doctrine_context:
entity_managers: # or connections:
Expand Down Expand Up @@ -184,7 +210,13 @@ php bin/console doctrine:database:create --conn=shop

### All supported commands

Every `doctrine:migrations:*` command supports the context options:
Always available (DBAL only):

| Command | Description |
|------------------------------|-----------------------------------------------------|
| `doctrine:database:create` | Create the database for each registered context |

When `doctrine/doctrine-migrations-bundle` is installed:

| Command | Description |
|---------------------------------------------|---------------------------------------------|
Expand All @@ -202,13 +234,7 @@ Every `doctrine:migrations:*` command supports the context options:
| `doctrine:migrations:dump-schema` | Dump the schema for a mapping |
| `doctrine:migrations:sync-metadata-storage` | Sync the metadata storage |

Always available:

| Command | Description |
|------------------------------|-----------------------------------------------------|
| `doctrine:database:create` | Create the database for each registered context |

When `doctrine/orm` is installed and configured:
When `doctrine/orm` is installed:

| Command | Description |
|----------------------------|----------------------------------------------|
Expand All @@ -218,7 +244,7 @@ When `doctrine/orm` is installed and configured:

### Schema filter

The bundle automatically registers a DBAL schema filter per context that hides the migration metadata table from `doctrine:schema:update` and `doctrine:schema:validate`. This prevents those commands from flagging the migration table as an unmanaged or extra table.
When `doctrine/doctrine-migrations-bundle` is installed, the bundle automatically registers a DBAL schema filter per context that hides the migration metadata table from `doctrine:schema:update` and `doctrine:schema:validate`. This prevents those commands from flagging the migration table as an unmanaged or extra table.

The filter activates only during schema update/validate commands and is otherwise transparent.

Expand Down
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
],
"require": {
"php": ">=8.4",
"doctrine/dbal": "^4.4",
"symfony/console": "^8.0"
"doctrine/doctrine-bundle": "^3.2"
},
"require-dev": {
"doctrine/coding-standard": "^13.0",
Expand Down
128 changes: 1 addition & 127 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,7 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Doctrine\Migrations\Configuration\Configuration as DoctrineMigrationsConfiguration;
use Doctrine\Migrations\DependencyFactory;
use Kraz\DoctrineContextBundle\Command\Doctrine\Database\CreateDatabaseCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\CurrentCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\DiffCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\DumpSchemaCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\ExecuteCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\GenerateCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\LatestCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\ListCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\MigrateCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\RollupCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\StatusCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\SyncMetadataCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\UpToDateCommand;
use Kraz\DoctrineContextBundle\Command\Doctrine\Migrations\VersionCommand;
use Kraz\DoctrineContextBundle\Configuration\Configuration as DoctrineContextConfiguration;
use Symfony\Component\DependencyInjection\ContainerInterface;

Expand All @@ -28,122 +13,11 @@
->set('doctrine.doctrine_context.configuration', DoctrineContextConfiguration::class)
->public()

->set('doctrine.doctrine_context.connection_configuration', DoctrineMigrationsConfiguration::class)
->abstract()

->set('doctrine.doctrine_context.dependency_factory', DependencyFactory::class)
->abstract()

// Commands
->set('doctrine.database_create_command.with_context', CreateDatabaseCommand::class)
->decorate('doctrine.database_create_command', null, 0, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:database:create'])

->set('doctrine_migrations.current_command.with_context', CurrentCommand::class)
->decorate('doctrine_migrations.current_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:current'])

->set('doctrine_migrations.diff_command.with_context', DiffCommand::class)
->decorate('doctrine_migrations.diff_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:diff'])

->set('doctrine_migrations.dump_schema_command.with_context', DumpSchemaCommand::class)
->decorate('doctrine_migrations.dump_schema_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:dump-schema'])

->set('doctrine_migrations.execute_command.with_context', ExecuteCommand::class)
->decorate('doctrine_migrations.execute_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:execute'])

->set('doctrine_migrations.generate_command.with_context', GenerateCommand::class)
->decorate('doctrine_migrations.generate_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:generate'])

->set('doctrine_migrations.latest_command.with_context', LatestCommand::class)
->decorate('doctrine_migrations.latest_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:latest'])

->set('doctrine_migrations.versions_command.with_context', ListCommand::class)
->decorate('doctrine_migrations.versions_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:list'])

->set('doctrine_migrations.migrate_command.with_context', MigrateCommand::class)
->decorate('doctrine_migrations.migrate_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:migrate'])

->set('doctrine_migrations.rollup_command.with_context', RollupCommand::class)
->decorate('doctrine_migrations.rollup_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:rollup'])

->set('doctrine_migrations.status_command.with_context', StatusCommand::class)
->decorate('doctrine_migrations.status_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:status'])

->set('doctrine_migrations.sync_metadata_command.with_context', SyncMetadataCommand::class)
->decorate('doctrine_migrations.sync_metadata_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:sync-metadata-storage'])

->set('doctrine_migrations.up_to_date_command.with_context', UpToDateCommand::class)
->decorate('doctrine_migrations.up_to_date_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:up-to-date'])

->set('doctrine_migrations.version_command.with_context', VersionCommand::class)
->decorate('doctrine_migrations.version_command')
->args([
service('.inner'),
service('doctrine.doctrine_context.configuration'),
])
->tag('console.command', ['command' => 'doctrine:migrations:version']);
->tag('console.command', ['command' => 'doctrine:database:create']);
};
Loading
Loading