Skip to content

Commit 24ba164

Browse files
authored
feat(database): support multiple databases in migrations and query builders (#1267)
1 parent 914ed58 commit 24ba164

File tree

52 files changed

+741
-201
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+741
-201
lines changed

packages/auth/src/CurrentUserInitializer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
use Tempest\Container\DynamicInitializer;
99
use Tempest\Container\Tag;
1010
use Tempest\Reflection\ClassReflector;
11+
use UnitEnum;
1112

1213
final readonly class CurrentUserInitializer implements DynamicInitializer
1314
{
14-
public function canInitialize(ClassReflector $class, ?string $tag): bool
15+
public function canInitialize(ClassReflector $class, null|string|UnitEnum $tag): bool
1516
{
1617
return $class->implements(CanAuthenticate::class);
1718
}
1819

19-
public function initialize(ClassReflector $class, ?string $tag, Container $container): object
20+
public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Container $container): object
2021
{
2122
$user = $container->get(Authenticator::class)->currentUser();
2223

packages/cache/src/CacheInitializer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@
99
use Tempest\Container\DynamicInitializer;
1010
use Tempest\Container\Singleton;
1111
use Tempest\Reflection\ClassReflector;
12+
use UnitEnum;
1213

1314
use function Tempest\env;
1415
use function Tempest\Support\str;
1516

1617
final readonly class CacheInitializer implements DynamicInitializer
1718
{
18-
public function canInitialize(ClassReflector $class, ?string $tag): bool
19+
public function canInitialize(ClassReflector $class, null|string|UnitEnum $tag): bool
1920
{
2021
return $class->getType()->matches(Cache::class);
2122
}
2223

2324
#[Singleton]
24-
public function initialize(ClassReflector $class, ?string $tag, Container $container): Cache
25+
public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Container $container): Cache
2526
{
2627
return new GenericCache(
2728
cacheConfig: $container->get(CacheConfig::class, $tag),

packages/cache/src/Testing/RestrictedCacheInitializer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88
use Tempest\Container\Singleton;
99
use Tempest\Discovery\SkipDiscovery;
1010
use Tempest\Reflection\ClassReflector;
11+
use UnitEnum;
1112

1213
#[SkipDiscovery]
1314
final class RestrictedCacheInitializer implements DynamicInitializer
1415
{
15-
public function canInitialize(ClassReflector $class, ?string $tag): bool
16+
public function canInitialize(ClassReflector $class, null|string|UnitEnum $tag): bool
1617
{
1718
return $class->getType()->matches(Cache::class);
1819
}
1920

2021
#[Singleton]
21-
public function initialize(ClassReflector $class, ?string $tag, Container $container): Cache
22+
public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Container $container): Cache
2223
{
2324
return new RestrictedCache($tag);
2425
}

packages/container/src/Container.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
use Tempest\Reflection\ClassReflector;
88
use Tempest\Reflection\FunctionReflector;
99
use Tempest\Reflection\MethodReflector;
10+
use UnitEnum;
1011

1112
interface Container
1213
{
1314
public function register(string $className, callable $definition): self;
1415

1516
public function unregister(string $className, bool $tagged = false): self;
1617

17-
public function singleton(string $className, mixed $definition, ?string $tag = null): self;
18+
public function singleton(string $className, mixed $definition, null|string|UnitEnum $tag = null): self;
1819

1920
public function config(object $config): self;
2021

@@ -23,9 +24,9 @@ public function config(object $config): self;
2324
* @param class-string<TClassName> $className
2425
* @return null|TClassName
2526
*/
26-
public function get(string $className, ?string $tag = null, mixed ...$params): mixed;
27+
public function get(string $className, null|string|UnitEnum $tag = null, mixed ...$params): mixed;
2728

28-
public function has(string $className, ?string $tag = null): bool;
29+
public function has(string $className, null|string|UnitEnum $tag = null): bool;
2930

3031
public function invoke(ClassReflector|MethodReflector|FunctionReflector|callable|string $method, mixed ...$params): mixed;
3132

packages/container/src/DynamicInitializer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
namespace Tempest\Container;
66

77
use Tempest\Reflection\ClassReflector;
8+
use UnitEnum;
89

910
interface DynamicInitializer
1011
{
11-
public function canInitialize(ClassReflector $class, ?string $tag): bool;
12+
public function canInitialize(ClassReflector $class, null|string|UnitEnum $tag): bool;
1213

13-
public function initialize(ClassReflector $class, ?string $tag, Container $container): object;
14+
public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Container $container): object;
1415
}

packages/container/src/GenericContainer.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Tempest\Reflection\ParameterReflector;
1818
use Tempest\Reflection\TypeReflector;
1919
use Throwable;
20+
use UnitEnum;
2021

2122
final class GenericContainer implements Container
2223
{
@@ -122,12 +123,12 @@ public function unregister(string $className, bool $tagged = false): self
122123
return $this;
123124
}
124125

125-
public function has(string $className, ?string $tag = null): bool
126+
public function has(string $className, null|string|UnitEnum $tag = null): bool
126127
{
127128
return isset($this->definitions[$className]) || isset($this->singletons[$this->resolveTaggedName($className, $tag)]);
128129
}
129130

130-
public function singleton(string $className, mixed $definition, ?string $tag = null): self
131+
public function singleton(string $className, mixed $definition, null|string|UnitEnum $tag = null): self
131132
{
132133
if ($definition instanceof HasTag) {
133134
$tag = $definition->tag;
@@ -156,7 +157,7 @@ public function config(object $config): self
156157
* @param class-string<TClassName> $className
157158
* @return null|TClassName
158159
*/
159-
public function get(string $className, ?string $tag = null, mixed ...$params): ?object
160+
public function get(string $className, null|string|UnitEnum $tag = null, mixed ...$params): ?object
160161
{
161162
$this->resolveChain();
162163

@@ -298,7 +299,7 @@ public function removeInitializer(ClassReflector|string $initializerClass): Cont
298299
return $this;
299300
}
300301

301-
private function resolve(string $className, ?string $tag = null, mixed ...$params): ?object
302+
private function resolve(string $className, null|string|UnitEnum $tag = null, mixed ...$params): ?object
302303
{
303304
$class = new ClassReflector($className);
304305

@@ -361,7 +362,7 @@ private function initializerForBuiltin(TypeReflector $target, string $tag): ?Ini
361362
return null;
362363
}
363364

364-
private function initializerForClass(ClassReflector $target, ?string $tag = null): null|Initializer|DynamicInitializer
365+
private function initializerForClass(ClassReflector $target, null|string|UnitEnum $tag = null): null|Initializer|DynamicInitializer
365366
{
366367
// Initializers themselves can't be initialized,
367368
// otherwise you'd end up with infinite loops
@@ -454,7 +455,7 @@ private function autowireDependencies(MethodReflector|FunctionReflector $method,
454455
return $dependencies;
455456
}
456457

457-
private function autowireDependency(ParameterReflector $parameter, ?string $tag, mixed $providedValue = null): mixed
458+
private function autowireDependency(ParameterReflector $parameter, null|string|UnitEnum $tag, mixed $providedValue = null): mixed
458459
{
459460
$parameterType = $parameter->getType();
460461

@@ -494,7 +495,7 @@ private function autowireDependency(ParameterReflector $parameter, ?string $tag,
494495
throw $lastThrowable ?? new CannotAutowireException($this->chain, new Dependency($parameter));
495496
}
496497

497-
private function autowireObjectDependency(TypeReflector $type, ?string $tag, mixed $providedValue, bool $lazy): mixed
498+
private function autowireObjectDependency(TypeReflector $type, null|string|UnitEnum $tag, mixed $providedValue, bool $lazy): mixed
498499
{
499500
// If the provided value is of the right type,
500501
// don't waste time autowiring, return it!
@@ -591,8 +592,12 @@ public function __clone(): void
591592
$this->chain = $this->chain?->clone();
592593
}
593594

594-
private function resolveTaggedName(string $className, ?string $tag): string
595+
private function resolveTaggedName(string $className, null|string|UnitEnum $tag): string
595596
{
597+
if ($tag instanceof UnitEnum) {
598+
$tag = $tag->name;
599+
}
600+
596601
return $tag
597602
? "{$className}#{$tag}"
598603
: $className;

packages/container/tests/ContainerTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Tempest\Container\Tests\Fixtures\ContainerObjectEInitializer;
3434
use Tempest\Container\Tests\Fixtures\DependencyWithBuiltinDependencies;
3535
use Tempest\Container\Tests\Fixtures\DependencyWithTaggedDependency;
36+
use Tempest\Container\Tests\Fixtures\EnumTag;
3637
use Tempest\Container\Tests\Fixtures\HasTagObject;
3738
use Tempest\Container\Tests\Fixtures\ImplementsInterfaceA;
3839
use Tempest\Container\Tests\Fixtures\InjectA;
@@ -258,6 +259,26 @@ public function test_tagged_singleton(): void
258259
$this->assertSame('cli', $container->get(TaggedDependency::class, 'cli')->name);
259260
}
260261

262+
public function test_tagged_singleton_with_enum(): void
263+
{
264+
$container = new GenericContainer();
265+
266+
$container->singleton(
267+
TaggedDependency::class,
268+
new TaggedDependency('web'),
269+
tag: EnumTag::FOO,
270+
);
271+
272+
$container->singleton(
273+
TaggedDependency::class,
274+
new TaggedDependency('cli'),
275+
tag: EnumTag::BAR,
276+
);
277+
278+
$this->assertSame('web', $container->get(TaggedDependency::class, EnumTag::FOO)->name);
279+
$this->assertSame('cli', $container->get(TaggedDependency::class, EnumTag::BAR)->name);
280+
}
281+
261282
public function test_tagged_singleton_with_initializer(): void
262283
{
263284
$container = new GenericContainer();

packages/container/tests/Fixtures/ContainerObjectEInitializer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
use Tempest\Container\DynamicInitializer;
99
use Tempest\Container\Tag;
1010
use Tempest\Reflection\ClassReflector;
11+
use UnitEnum;
1112

1213
final class ContainerObjectEInitializer implements DynamicInitializer
1314
{
14-
public function canInitialize(ClassReflector $class, ?string $tag): bool
15+
public function canInitialize(ClassReflector $class, null|string|UnitEnum $tag): bool
1516
{
1617
return $class->getName() === ContainerObjectE::class;
1718
}
1819

19-
public function initialize(ClassReflector $class, ?string $tag, Container $container): object
20+
public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Container $container): object
2021
{
2122
return new ContainerObjectE();
2223
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Tempest\Container\Tests\Fixtures;
4+
5+
enum EnumTag
6+
{
7+
case FOO;
8+
case BAR;
9+
}

packages/database/src/Builder/QueryBuilders/CountQueryBuilder.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Tempest\Database\Builder\ModelDefinition;
88
use Tempest\Database\Builder\TableDefinition;
99
use Tempest\Database\Exceptions\CannotCountDistinctWithoutSpecifyingAColumn;
10+
use Tempest\Database\OnDatabase;
1011
use Tempest\Database\Query;
1112
use Tempest\Database\QueryStatements\CountStatement;
1213
use Tempest\Database\QueryStatements\WhereStatement;
@@ -17,7 +18,7 @@
1718
*/
1819
final class CountQueryBuilder implements BuildsQuery
1920
{
20-
use HasConditions;
21+
use HasConditions, OnDatabase;
2122

2223
private ?ModelDefinition $modelDefinition;
2324

@@ -95,7 +96,7 @@ public function toSql(): string
9596

9697
public function build(mixed ...$bindings): Query
9798
{
98-
return new Query($this->count, [...$this->bindings, ...$bindings]);
99+
return new Query($this->count, [...$this->bindings, ...$bindings])->onDatabase($this->onDatabase);
99100
}
100101

101102
private function resolveTable(string|object $model): TableDefinition

0 commit comments

Comments
 (0)