Skip to content

Commit 04b5bd6

Browse files
authored
refactor(database): remove DatabaseModel interface (#1076)
1 parent 6af05d5 commit 04b5bd6

File tree

123 files changed

+2442
-1011
lines changed

Some content is hidden

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

123 files changed

+2442
-1011
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"src/Tempest/CommandBus/src/functions.php",
119119
"src/Tempest/Container/src/functions.php",
120120
"src/Tempest/Core/src/functions.php",
121+
"src/Tempest/Database/src/functions.php",
121122
"src/Tempest/Debug/src/functions.php",
122123
"src/Tempest/EventBus/src/functions.php",
123124
"src/Tempest/Mapper/src/functions.php",

src/Tempest/Auth/src/AuthConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function __construct(
1212
/** @var class-string<\Tempest\Auth\Authenticator> */
1313
public string $authenticatorClass = SessionAuthenticator::class,
1414

15-
/** @var class-string<\Tempest\Database\DatabaseModel> */
15+
/** @var class-string */
1616
public string $userModelClass = User::class,
1717
) {}
1818
}

src/Tempest/Auth/src/CanAuthenticate.php

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

55
namespace Tempest\Auth;
66

7-
use Tempest\Database\DatabaseModel;
7+
use Tempest\Database\Id;
88

9-
interface CanAuthenticate extends DatabaseModel
9+
interface CanAuthenticate
1010
{
11+
public ?Id $id {
12+
get;
13+
}
1114
}

src/Tempest/Auth/src/Install/Permission.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
namespace Tempest\Auth\Install;
66

77
use BackedEnum;
8-
use Tempest\Database\DatabaseModel;
98
use Tempest\Database\IsDatabaseModel;
109
use UnitEnum;
1110

12-
final class Permission implements DatabaseModel
11+
final class Permission
1312
{
1413
use IsDatabaseModel;
1514

src/Tempest/Auth/src/Install/User.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
use SensitiveParameter;
99
use Tempest\Auth\CanAuthenticate;
1010
use Tempest\Auth\CanAuthorize;
11-
use Tempest\Database\DatabaseModel;
1211
use Tempest\Database\IsDatabaseModel;
1312
use UnitEnum;
1413

1514
use function Tempest\Support\arr;
1615

17-
final class User implements DatabaseModel, CanAuthenticate, CanAuthorize
16+
final class User implements CanAuthenticate, CanAuthorize
1817
{
1918
use IsDatabaseModel;
2019

@@ -79,7 +78,7 @@ private function resolvePermission(string|UnitEnum|Permission $permission): Perm
7978
$permission instanceof UnitEnum => $permission->name,
8079
};
8180

82-
$permission = Permission::query()->whereField('name', $name)->first();
81+
$permission = Permission::select()->whereField('name', $name)->first();
8382

8483
return $permission ?? new Permission($name)->save();
8584
}

src/Tempest/Auth/src/Install/UserPermission.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44

55
namespace Tempest\Auth\Install;
66

7-
use Tempest\Database\DatabaseModel;
87
use Tempest\Database\IsDatabaseModel;
98

10-
final class UserPermission implements DatabaseModel
9+
final class UserPermission
1110
{
1211
use IsDatabaseModel;
1312

src/Tempest/Auth/src/SessionAuthenticator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function __construct(
1818

1919
public function login(CanAuthenticate $user): void
2020
{
21-
$this->session->set(self::USER_KEY, $user->getId());
21+
$this->session->set(self::USER_KEY, $user->id);
2222
}
2323

2424
public function logout(): void
@@ -37,8 +37,8 @@ public function currentUser(): ?CanAuthenticate
3737

3838
$userModelClass = new ClassReflector($this->authConfig->userModelClass);
3939

40-
/** @var \Tempest\Database\Builder\ModelQueryBuilder<\Tempest\Auth\CanAuthenticate> $query */
41-
$query = $userModelClass->callStatic('query');
40+
/** @var \Tempest\Database\Builder\QueryBuilders\SelectQueryBuilder<\Tempest\Auth\CanAuthenticate> $query */
41+
$query = $userModelClass->callStatic('select');
4242

4343
return $query->with('userPermissions.permission')->get($id);
4444
}

src/Tempest/Database/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
"autoload": {
1616
"psr-4": {
1717
"Tempest\\Database\\": "src"
18-
}
18+
},
19+
"files": [
20+
"src/functions.php"
21+
]
1922
},
2023
"autoload-dev": {
2124
"psr-4": {

src/Tempest/Database/src/Builder/FieldName.php renamed to src/Tempest/Database/src/Builder/FieldDefinition.php

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,42 @@
55
namespace Tempest\Database\Builder;
66

77
use Stringable;
8-
use Tempest\Database\DatabaseModel;
98
use Tempest\Mapper\CasterFactory;
109
use Tempest\Reflection\ClassReflector;
10+
use Tempest\Support\Arr\ImmutableArray;
1111

1212
use function Tempest\get;
1313

14-
final class FieldName implements Stringable
14+
final class FieldDefinition implements Stringable
1515
{
1616
public function __construct(
17-
public readonly TableName $tableName,
18-
public readonly string $fieldName,
17+
public readonly TableDefinition $tableDefinition,
18+
public readonly string $name,
1919
public ?string $as = null,
2020
) {}
2121

22-
/** @return \Tempest\Database\Builder\FieldName[] */
23-
public static function make(ClassReflector $class, ?TableName $tableName = null): array
22+
/** @return ImmutableArray<\Tempest\Database\Builder\FieldDefinition> */
23+
public static function all(ClassReflector $class, ?TableDefinition $tableDefinition = null): ImmutableArray
2424
{
2525
$casterFactory = get(CasterFactory::class);
26-
$fieldNames = [];
27-
$tableName ??= $class->callStatic('table');
26+
$fieldDefinitions = [];
27+
$tableDefinition ??= new ModelDefinition($class->getName())->getTableDefinition();
2828

2929
foreach ($class->getPublicProperties() as $property) {
3030
// Don't include the field if it's a 1:1 or n:1 relation
31-
if ($property->getType()->matches(DatabaseModel::class)) {
31+
if ($property->getType()->isRelation()) {
3232
continue;
3333
}
3434

3535
// Don't include the field if it's a 1:n relation
36-
if ($property->getIterableType()?->matches(DatabaseModel::class)) {
36+
if ($property->getIterableType()?->isRelation()) {
3737
continue;
3838
}
3939

4040
$caster = $casterFactory->forProperty($property);
4141

4242
if ($caster !== null) {
43-
$fieldNames[] = new FieldName($tableName, $property->getName());
43+
$fieldDefinitions[] = new FieldDefinition($tableDefinition, $property->getName());
4444

4545
continue;
4646
}
@@ -49,10 +49,10 @@ public static function make(ClassReflector $class, ?TableName $tableName = null)
4949
continue;
5050
}
5151

52-
$fieldNames[] = new FieldName($tableName, $property->getName());
52+
$fieldDefinitions[] = new FieldDefinition($tableDefinition, $property->getName());
5353
}
5454

55-
return $fieldNames;
55+
return new ImmutableArray($fieldDefinitions);
5656
}
5757

5858
public function as(string $as): self
@@ -64,16 +64,16 @@ public function as(string $as): self
6464

6565
public function withAlias(): self
6666
{
67-
$tableName = $this->tableName->as ?? $this->tableName->tableName;
67+
$name = $this->tableDefinition->as ?? $this->tableDefinition->name;
6868

69-
return $this->as($tableName . '.' . $this->fieldName);
69+
return $this->as($name . '.' . $this->name);
7070
}
7171

7272
public function __toString(): string
7373
{
74-
$tableName = $this->tableName->as ?? $this->tableName->tableName;
74+
$tableName = $this->tableDefinition->as ?? $this->tableDefinition->name;
7575

76-
$string = "`{$tableName}`.`{$this->fieldName}`";
76+
$string = "`{$tableName}`.`{$this->name}`";
7777

7878
if ($this->as) {
7979
$string .= " AS `{$this->as}`";

src/Tempest/Database/src/Builder/ModelDefinition.php

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,50 @@
44

55
namespace Tempest\Database\Builder;
66

7+
use ReflectionException;
78
use Tempest\Database\BelongsTo;
89
use Tempest\Database\Builder\Relations\BelongsToRelation;
910
use Tempest\Database\Builder\Relations\HasManyRelation;
1011
use Tempest\Database\Builder\Relations\HasOneRelation;
12+
use Tempest\Database\Config\DatabaseConfig;
1113
use Tempest\Database\Eager;
1214
use Tempest\Database\HasMany;
1315
use Tempest\Database\HasOne;
16+
use Tempest\Database\TableName;
1417
use Tempest\Reflection\ClassReflector;
18+
use Tempest\Support\Arr\ImmutableArray;
1519

16-
use function Tempest\reflect;
20+
use function Tempest\get;
1721

1822
final readonly class ModelDefinition
1923
{
20-
public function __construct(
21-
/** @var class-string<\Tempest\Database\DatabaseModel> $modelClass */
22-
private string $modelClass,
23-
) {}
24+
private ClassReflector $modelClass;
25+
26+
public static function tryFrom(string|object $model): ?self
27+
{
28+
try {
29+
return new self($model);
30+
} catch (ReflectionException) {
31+
return null;
32+
}
33+
}
34+
35+
public function __construct(string|object $model)
36+
{
37+
if ($model instanceof ClassReflector) {
38+
$this->modelClass = $model;
39+
} else {
40+
$this->modelClass = new ClassReflector($model);
41+
}
42+
}
2443

2544
/** @return \Tempest\Database\Builder\Relations\Relation[] */
2645
public function getRelations(string $relationName): array
2746
{
2847
$relations = [];
29-
$class = reflect($this->modelClass);
3048
$relationNames = explode('.', $relationName);
31-
$alias = TableName::for($class)->tableName;
49+
$alias = $this->getTableDefinition()->name;
50+
$class = $this->modelClass;
3251

3352
foreach ($relationNames as $relationNamePart) {
3453
$property = $class->getProperty($relationNamePart);
@@ -68,7 +87,7 @@ public function getEagerRelations(): array
6887
{
6988
$relations = [];
7089

71-
foreach ($this->buildEagerRelationNames(reflect($this->modelClass)) as $relationName) {
90+
foreach ($this->buildEagerRelationNames($this->modelClass) as $relationName) {
7291
foreach ($this->getRelations($relationName) as $relation) {
7392
$relations[$relation->getRelationName()] = $relation;
7493
}
@@ -96,22 +115,30 @@ private function buildEagerRelationNames(ClassReflector $class): array
96115
return $relations;
97116
}
98117

99-
public function getTableName(): TableName
118+
public function getTableDefinition(): TableDefinition
100119
{
101-
return $this->modelClass::table();
120+
$specificName = $this->modelClass
121+
->getAttribute(TableName::class)
122+
?->name;
123+
124+
$conventionalName = get(DatabaseConfig::class)
125+
->namingStrategy
126+
->getName($this->modelClass->getName());
127+
128+
return new TableDefinition($specificName ?? $conventionalName);
102129
}
103130

104-
public function getFieldName(string $fieldName): FieldName
131+
public function getFieldDefinition(string $name): FieldDefinition
105132
{
106-
return new FieldName(
107-
tableName: $this->getTableName(),
108-
fieldName: $fieldName,
133+
return new FieldDefinition(
134+
tableDefinition: $this->getTableDefinition(),
135+
name: $name,
109136
);
110137
}
111138

112-
/** @return \Tempest\Database\Builder\FieldName[] */
113-
public function getFieldNames(): array
139+
/** @return ImmutableArray<array-key, \Tempest\Database\Builder\FieldDefinition> */
140+
public function getFieldDefinitions(): ImmutableArray
114141
{
115-
return FieldName::make(reflect($this->modelClass));
142+
return FieldDefinition::all($this->modelClass);
116143
}
117144
}

0 commit comments

Comments
 (0)