Skip to content

Commit 73ec523

Browse files
committed
refactor: support context objects with data
1 parent a026a63 commit 73ec523

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

+373
-307
lines changed

packages/auth/tests/OAuthTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
use Tempest\Auth\OAuth\OAuthUser;
2727
use Tempest\Container\Container;
2828
use Tempest\Container\GenericContainer;
29-
use Tempest\Mapper\Context;
3029
use Tempest\Mapper\MapperConfig;
3130
use Tempest\Mapper\Mappers\ArrayToObjectMapper;
3231
use Tempest\Mapper\ObjectFactory;
@@ -38,7 +37,7 @@ final class OAuthTest extends TestCase
3837
}
3938

4039
private ObjectFactory $factory {
41-
get => $this->factory ??= new ObjectFactory(new MapperConfig([Context::DEFAULT => [ArrayToObjectMapper::class]]), $this->container);
40+
get => $this->factory ??= new ObjectFactory(new MapperConfig([ArrayToObjectMapper::class]), $this->container);
4241
}
4342

4443
#[Before]

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use Closure;
66
use Tempest\Database\Builder\ModelInspector;
7-
use Tempest\Database\Config\DatabaseDialect;
87
use Tempest\Database\Database;
8+
use Tempest\Database\DatabaseContext;
99
use Tempest\Database\Exceptions\HasManyRelationCouldNotBeInsterted;
1010
use Tempest\Database\Exceptions\HasOneRelationCouldNotBeInserted;
1111
use Tempest\Database\Exceptions\ModelDidNotHavePrimaryColumn;
@@ -16,7 +16,6 @@
1616
use Tempest\Database\QueryStatements\InsertStatement;
1717
use Tempest\Database\Virtual;
1818
use Tempest\Intl;
19-
use Tempest\Mapper\Context;
2019
use Tempest\Mapper\SerializerFactory;
2120
use Tempest\Reflection\ClassReflector;
2221
use Tempest\Reflection\PropertyReflector;
@@ -48,6 +47,10 @@ final class InsertQueryBuilder implements BuildsQuery
4847
get => get(Database::class, $this->onDatabase);
4948
}
5049

50+
private DatabaseContext $context {
51+
get => new DatabaseContext(dialect: $this->database->dialect);
52+
}
53+
5154
/**
5255
* @param class-string<TModel>|string|TModel $model
5356
*/
@@ -477,13 +480,10 @@ private function serializeValue(PropertyReflector $property, mixed $value): mixe
477480
return null;
478481
}
479482

480-
$context = match ($this->database->dialect) {
481-
DatabaseDialect::MYSQL => Context::DATABASE_MYSQL,
482-
DatabaseDialect::POSTGRESQL => Context::DATABASE_POSTGRESQL,
483-
DatabaseDialect::SQLITE => Context::DATABASE_SQLITE,
484-
};
485-
486-
return $this->serializerFactory->forProperty($property, $context)?->serialize($value) ?? $value;
483+
return $this->serializerFactory
484+
->in($this->context)
485+
->forProperty($property)
486+
?->serialize($value) ?? $value;
487487
}
488488

489489
private function serializeIterableValue(string $key, mixed $value): mixed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use Closure;
88
use Tempest\Database\Builder\ModelInspector;
9+
use Tempest\Database\Database;
10+
use Tempest\Database\DatabaseContext;
911
use Tempest\Database\Direction;
1012
use Tempest\Database\Exceptions\ModelDidNotHavePrimaryColumn;
1113
use Tempest\Database\Mappers\SelectModelMapper;
@@ -27,6 +29,7 @@
2729
use Tempest\Support\Str\ImmutableString;
2830

2931
use function Tempest\Database\inspect;
32+
use function Tempest\get;
3033
use function Tempest\Mapper\map;
3134

3235
/**
@@ -162,6 +165,7 @@ public function all(mixed ...$bindings): array
162165

163166
return map($query->fetch())
164167
->with(SelectModelMapper::class)
168+
->in(new DatabaseContext(get(Database::class, $this->onDatabase)->dialect))
165169
->to($this->model->getName());
166170
}
167171

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use Tempest\Database\Builder\ModelInspector;
66
use Tempest\Database\Builder\WhereOperator;
7-
use Tempest\Database\Config\DatabaseDialect;
87
use Tempest\Database\Database;
8+
use Tempest\Database\DatabaseContext;
99
use Tempest\Database\Exceptions\CouldNotUpdateRelation;
1010
use Tempest\Database\Exceptions\HasManyRelationCouldNotBeUpdated;
1111
use Tempest\Database\Exceptions\HasOneRelationCouldNotBeUpdated;
@@ -17,7 +17,6 @@
1717
use Tempest\Database\QueryStatements\WhereStatement;
1818
use Tempest\Database\Virtual;
1919
use Tempest\Intl;
20-
use Tempest\Mapper\Context;
2120
use Tempest\Mapper\SerializerFactory;
2221
use Tempest\Reflection\ClassReflector;
2322
use Tempest\Reflection\PropertyReflector;
@@ -52,6 +51,10 @@ final class UpdateQueryBuilder implements BuildsQuery, SupportsWhereStatements
5251
get => get(Database::class, $this->onDatabase);
5352
}
5453

54+
private DatabaseContext $context {
55+
get => new DatabaseContext(dialect: $this->database->dialect);
56+
}
57+
5558
public ImmutableArray $wheres {
5659
get => $this->update->where;
5760
}
@@ -260,13 +263,9 @@ private function resolveRelationValue(PropertyReflector $property, string $colum
260263

261264
private function serializeValue(PropertyReflector $property, mixed $value): mixed
262265
{
263-
$context = match ($this->database->dialect) {
264-
DatabaseDialect::MYSQL => Context::DATABASE_MYSQL,
265-
DatabaseDialect::POSTGRESQL => Context::DATABASE_POSTGRESQL,
266-
DatabaseDialect::SQLITE => Context::DATABASE_SQLITE,
267-
};
268-
269-
$serializer = $this->serializerFactory->forProperty($property, $context);
266+
$serializer = $this->serializerFactory
267+
->in($this->context)
268+
->forProperty($property);
270269

271270
if ($value !== null && $serializer !== null) {
272271
return $serializer->serialize($value);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tempest\Database;
4+
5+
use Tempest\Database\Config\DatabaseDialect;
6+
use Tempest\Mapper\Context;
7+
8+
final class DatabaseContext implements Context
9+
{
10+
private(set) string $key = self::class;
11+
12+
public function __construct(
13+
private(set) DatabaseDialect $dialect,
14+
) {}
15+
}

packages/database/src/GenericDatabase.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Tempest\Database\Connection\Connection;
1313
use Tempest\Database\Exceptions\QueryWasInvalid;
1414
use Tempest\Database\Transactions\TransactionManager;
15-
use Tempest\Mapper\Context;
1615
use Tempest\Mapper\SerializerFactory;
1716
use Throwable;
1817
use UnitEnum;
@@ -30,12 +29,8 @@ final class GenericDatabase implements Database
3029
get => $this->connection->config->tag;
3130
}
3231

33-
private string $context {
34-
get => match ($this->dialect) {
35-
DatabaseDialect::POSTGRESQL => Context::DATABASE_POSTGRESQL,
36-
DatabaseDialect::MYSQL => Context::DATABASE_MYSQL,
37-
DatabaseDialect::SQLITE => Context::DATABASE_SQLITE,
38-
};
32+
private DatabaseContext $context {
33+
get => new DatabaseContext(dialect: $this->dialect);
3934
}
4035

4136
public function __construct(
@@ -139,7 +134,7 @@ private function resolveBindings(Query $query): array
139134
foreach ($query->bindings as $key => $value) {
140135
if ($value instanceof Query) {
141136
$value = $value->execute();
142-
} elseif ($serializer = $this->serializerFactory->forValue($value, $this->context)) {
137+
} elseif ($serializer = $this->serializerFactory->in($this->context)->forValue($value)) {
143138
$value = $serializer->serialize($value);
144139
}
145140

packages/database/src/Mappers/SelectModelMapper.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Tempest\Database\HasMany;
88
use Tempest\Database\HasOne;
99
use Tempest\Discovery\SkipDiscovery;
10+
use Tempest\Mapper\Context;
1011
use Tempest\Mapper\Mapper;
1112
use Tempest\Support\Arr\MutableArray;
1213

@@ -17,6 +18,10 @@
1718
#[SkipDiscovery]
1819
final class SelectModelMapper implements Mapper
1920
{
21+
public function __construct(
22+
private Context $context,
23+
) {}
24+
2025
public function canMap(mixed $from, mixed $to): bool
2126
{
2227
return false;
@@ -33,7 +38,10 @@ public function map(mixed $from, mixed $to): array
3338
->map(fn (array $rows) => $this->normalizeFields($model, $rows))
3439
->values();
3540

36-
$objects = map($parsed->toArray())->collection()->to($to);
41+
$objects = map($parsed->toArray())
42+
->in($this->context)
43+
->collection()
44+
->to($to);
3745

3846
foreach ($objects as $i => $object) {
3947
foreach ($model->getRelations() as $relation) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Database\Serializers;
6+
7+
use Tempest\Database\Config\DatabaseDialect;
8+
use Tempest\Database\DatabaseContext;
9+
use Tempest\Mapper\Attributes\Context;
10+
use Tempest\Mapper\Exceptions\ValueCouldNotBeSerialized;
11+
use Tempest\Mapper\Serializer;
12+
13+
#[Context(DatabaseContext::class)]
14+
final class BooleanSerializer implements Serializer
15+
{
16+
public function __construct(
17+
private DatabaseContext $context,
18+
) {}
19+
20+
public static function for(): array
21+
{
22+
return ['bool', 'boolean'];
23+
}
24+
25+
public function serialize(mixed $input): string
26+
{
27+
if (! is_bool($input)) {
28+
throw new ValueCouldNotBeSerialized('boolean');
29+
}
30+
31+
return match ($this->context->dialect) {
32+
DatabaseDialect::POSTGRESQL => $input ? 'true' : 'false',
33+
default => $input ? '1' : '0',
34+
};
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Database\Serializers;
6+
7+
use DateTimeInterface as NativeDateTimeInterface;
8+
use Tempest\Database\DatabaseContext;
9+
use Tempest\DateTime\DateTime;
10+
use Tempest\DateTime\DateTimeInterface;
11+
use Tempest\DateTime\FormatPattern;
12+
use Tempest\Mapper\Attributes\Context;
13+
use Tempest\Mapper\Exceptions\ValueCouldNotBeSerialized;
14+
use Tempest\Mapper\Serializer;
15+
16+
#[Context(DatabaseContext::class)]
17+
final readonly class DateTimeSerializer implements Serializer
18+
{
19+
public static function for(): array
20+
{
21+
return [DateTime::class, DateTimeInterface::class, NativeDateTimeInterface::class];
22+
}
23+
24+
public function serialize(mixed $input): string
25+
{
26+
if ($input instanceof NativeDateTimeInterface) {
27+
$input = DateTime::parse($input);
28+
}
29+
30+
if (! $input instanceof DateTimeInterface) {
31+
throw new ValueCouldNotBeSerialized(DateTimeInterface::class);
32+
}
33+
34+
return $input->format(FormatPattern::SQL_DATE_TIME);
35+
}
36+
}

packages/database/src/Serializers/MysqlBooleanSerializer.php

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)