Skip to content

Remove parameter name usage for AutowireDatabase #13

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

Merged
merged 3 commits into from
Dec 9, 2023
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
58 changes: 37 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ mongodb:
clients:
default:
uri: '%env(MONGODB_URI)%'
default_database: #...
uri_options: #...
driver_options: #...
```
Expand Down Expand Up @@ -96,7 +97,8 @@ class MyService
}
```

If you register multiple clients, you can autowire them by name + `Client` suffix:
If you register multiple clients, you can autowire them by using the client name with a `Client` suffix as parameter
name:

```php
use MongoDB\Bundle\Attribute\AutowireClient;
Expand All @@ -105,6 +107,7 @@ use MongoDB\Client;
class MyService
{
public function __construct(
// Will autowire the client with the id "second"
private Client $secondClient,
) {}
}
Expand All @@ -119,16 +122,16 @@ use MongoDB\Client;
class MyService
{
public function __construct(
#[AutowireClient('second')]
#[AutowireClient('second')]
private Client $client,
) {}
}
```

## Database and Collection Usage

The client service provides access to databases and collections. You can access a database by calling the `selectDatabase`
method, passing the database name and potential options:
The client service provides access to databases and collections. You can access a database by calling the
`selectDatabase` method, passing the database name and potential options:

```php
use MongoDB\Client;
Expand All @@ -146,7 +149,7 @@ class MyService
}
```

An alternative to this is using the `AutowireDatabase` attribute, referencing the database name:
An alternative to this is using the `#[AutowireDatabase]` attribute, referencing the database name:

```php
use MongoDB\Bundle\Attribute\AutowireDatabase;
Expand All @@ -161,21 +164,9 @@ class MyService
}
```

You can also omit the `database` option if the property name matches the database name.
In the following example the database name is `myDatabase`, inferred from the property name:

```php
use MongoDB\Bundle\Attribute\AutowireCollection;
use MongoDB\Collection;

class MyService
{
public function __construct(
#[AutowireCollection()]
private Collection $myDatabase,
) {}
}
```
If you don't specify a database name in the attribute, the default database name (specified in the `default_database`
configuration option) will be used. If you did not define a default database, the database name has to be specified in
the attribute.

If you have more than one client defined, you can also reference the client:

Expand All @@ -193,7 +184,7 @@ class MyService
```

To inject a collection, you can either call the `selectCollection` method on a `Client` or `Database` instance.
For convenience, the `AutowireCollection` attribute provides a quicker alternative:
For convenience, the `#[AutowireCollection]` attribute provides a quicker alternative:

```php
use MongoDB\Bundle\Attribute\AutowireCollection;
Expand Down Expand Up @@ -230,6 +221,7 @@ class MyService
```

If you have more than one client defined, you can also reference the client:

```php
use MongoDB\Bundle\Attribute\AutowireCollection;
use MongoDB\Collection;
Expand All @@ -245,3 +237,27 @@ class MyService
) {}
}
```

By specifiying the `default_database` option in the configuration, you can omit the `database` option in the
`AutowireCollection` attribute:

```diff
mongodb:
clients:
default:
uri: '%env(MONGODB_URI)%'
+ default_database: 'myDatabase'
```

```php
use MongoDB\Bundle\Attribute\AutowireCollection;
use MongoDB\Collection;

class MyService
{
public function __construct(
#[AutowireCollection]
private Collection $myCollection,
) {}
}
```
16 changes: 11 additions & 5 deletions src/Attribute/AutowireDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,28 @@
use Symfony\Component\DependencyInjection\Reference;

use function is_string;
use function sprintf;

/**
* Autowires a MongoDB database.
*/
#[Attribute(Attribute::TARGET_PARAMETER)]
final class AutowireDatabase extends AutowireCallable
{
private readonly string $serviceId;

public function __construct(
private readonly ?string $database = null,
?string $client = null,
private readonly array $options = [],
bool|string $lazy = false,
) {
$callable = $client === null
? [new Reference(Client::class), 'selectDatabase']
: [new Reference(MongoDBExtension::createClientServiceId($client)), 'selectDatabase'];
$this->serviceId = $client === null
? Client::class
: MongoDBExtension::createClientServiceId($client);

parent::__construct(
callable: $callable,
callable: [new Reference($this->serviceId), 'selectDatabase'],
lazy: $lazy,
);
}
Expand All @@ -57,7 +60,10 @@ public function buildDefinition(mixed $value, ?string $type, ReflectionParameter
{
return (new Definition(is_string($this->lazy) ? $this->lazy : ($type ?: Database::class)))
->setFactory($value)
->setArguments([$this->database ?? $parameter->getName(), $this->options])
->setArguments([
$this->database ?? sprintf('%%%s.default_database%%', $this->serviceId),
$this->options,
])
->setLazy($this->lazy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ public function withoutArguments(
/** @see AutowireClientTest::testWithCustomClientSetViaOptions() */
#[Route('/with-custom-client')]
public function withCustomClient(
#[AutowireDatabase(client: FunctionalTestCase::CLIENT_ID_SECONDARY)]
Database $google,
#[AutowireDatabase(database: 'google', client: FunctionalTestCase::CLIENT_ID_SECONDARY)]
Database $database,
): JsonResponse {
$this->insertDocumentForDatabase($google, FunctionalTestCase::COLLECTION_USERS);
$this->insertDocumentForDatabase($database, FunctionalTestCase::COLLECTION_USERS);

return new JsonResponse();
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/Attribute/AutowireDatabaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static function (Database $mydb): void {

$this->assertSame(Database::class, $definition->getClass());
$this->assertEquals($autowire->value, $definition->getFactory());
$this->assertSame('mydb', $definition->getArgument(0));
$this->assertSame('%MongoDB\Client.default_database%', $definition->getArgument(0));
Copy link
Collaborator

Choose a reason for hiding this comment

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

That's an ugly parameter name. Can we find something more conventional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's an ugly parameter name. Can we find something more conventional?

I'll address that in a separate PR - maybe we can always use <clientId>.default_database

}

public function testDatabase(): void
Expand Down Expand Up @@ -98,7 +98,7 @@ static function (Database $mydb): void {

$this->assertSame(Database::class, $definition->getClass());
$this->assertEquals($autowire->value, $definition->getFactory());
$this->assertSame('mydb', $definition->getArgument(0));
$this->assertSame('%mongodb.client.default.default_database%', $definition->getArgument(0));
$this->assertSame(['foo' => 'bar'], $definition->getArgument(1));
}
}