Skip to content

Commit ea70766

Browse files
committed
wip
1 parent f64d93d commit ea70766

File tree

11 files changed

+73
-49
lines changed

11 files changed

+73
-49
lines changed

packages/database/src/BelongsTo.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@ public function getSelectFields(): ImmutableArray
5757

5858
return $relationModel
5959
->getSelectFields()
60-
->map(fn ($field) => new FieldStatement(
61-
$relationModel->getTableName() . '.' . $field,
62-
)
63-
->withAlias()
64-
->withAliasPrefix($this->parent));
60+
->map(function ($field) use ($relationModel) {
61+
return new FieldStatement(
62+
$relationModel->getTableName() . '.' . $field,
63+
)->withAlias(
64+
sprintf('%s.%s', $this->property->getName(), $field)
65+
)->withAliasPrefix($this->parent);
66+
});
6567
}
6668

6769
public function getJoinStatement(): JoinStatement

packages/database/src/Builder/ModelInspector.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,10 @@ public function resolveRelations(string $relationString, string $parent = ''): a
260260
$newParent = ltrim(sprintf(
261261
'%s.%s',
262262
$parent,
263-
$relationModel->getTableName(),
263+
$currentRelationName,
264264
), '.');
265265

266-
$relations = [$relationModel->getTableName() => $currentRelation];
266+
$relations = [$currentRelationName => $currentRelation];
267267

268268
return [...$relations, ...$relationModel->resolveRelations($newRelationString, $newParent)];
269269
}

packages/database/src/HasMany.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ public function getSelectFields(): ImmutableArray
4444
->getSelectFields()
4545
->map(fn ($field) => new FieldStatement(
4646
$relationModel->getTableName() . '.' . $field,
47-
)
48-
->withAlias()
49-
->withAliasPrefix($this->parent));
47+
)->withAlias(
48+
sprintf('%s.%s', $this->property->getName(), $field),
49+
)->withAliasPrefix($this->parent));
5050
}
5151

5252
public function primaryKey(): string

packages/database/src/HasOne.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ public function getSelectFields(): ImmutableArray
4444
->getSelectFields()
4545
->map(fn ($field) => new FieldStatement(
4646
$relationModel->getTableName() . '.' . $field,
47-
)
48-
->withAlias()
49-
->withAliasPrefix($this->parent));
47+
)->withAlias(
48+
sprintf('%s.%s', $this->property->getName(), $field)
49+
)->withAliasPrefix($this->parent));
5050
}
5151

5252
public function getJoinStatement(): JoinStatement

packages/database/src/Mappers/SelectModelMapper.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ public function map(mixed $from, mixed $to): array
3333
->groupBy(function (array $data) use ($idField) {
3434
return $data[$idField];
3535
})
36-
->map(fn (array $rows) => $this->normalizeFields($model, $rows));
36+
->map(fn (array $rows) => $this->normalizeFields($model, $rows))
37+
->values();
3738

38-
return map($parsed->values()->toArray())->collection()->to($to);
39+
return map($parsed->toArray())->collection()->to($to);
3940
}
4041

4142
private function normalizeFields(ModelInspector $model, array $rows): array
@@ -98,12 +99,21 @@ public function normalizeRow(ModelInspector $model, array $row, MutableArray $da
9899
$key .= $relation->name . '.';
99100
$originalKey .= $relation->name . '.';
100101
} elseif ($relation instanceof HasMany) {
101-
$id = $data->get($key . $relation->idField())
102+
$hasManyId = $data->get($key . $relation->idField())
102103
?? $row[$originalKey . $relation->idField()]
103104
?? null;
104105

105-
$key .= $relation->name . '.' . $id . '.';
106106
$originalKey .= $relation->name . '.';
107+
108+
if (! $data->has(trim($originalKey, '.'))) {
109+
$data->set(trim($originalKey, '.'), []);
110+
}
111+
112+
if ($hasManyId === null) {
113+
break;
114+
}
115+
116+
$key .= $relation->name . '.' . $hasManyId . '.';
107117
} else {
108118
$key .= $part;
109119
break;
@@ -112,7 +122,9 @@ public function normalizeRow(ModelInspector $model, array $row, MutableArray $da
112122
$currentModel = model($relation);
113123
}
114124

115-
$data->set($key, $value);
125+
if ($key) {
126+
$data->set($key, $value);
127+
}
116128
}
117129

118130
return $data->toArray();

packages/database/src/QueryStatements/FieldStatement.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
final class FieldStatement implements QueryStatement
1212
{
13-
private bool $withAlias = false;
13+
private null|bool|string $alias = null;
1414
private ?string $aliasPrefix = null;
1515

1616
public function __construct(
@@ -25,13 +25,20 @@ public function compile(DatabaseDialect $dialect): string
2525

2626
if (count($parts) === 1) {
2727
$alias = null;
28+
$aliasPrefix = $this->aliasPrefix ? "{$this->aliasPrefix}." : '';
2829

29-
if ($this->withAlias) {
30+
if ($this->alias === true) {
3031
$alias = sprintf(
3132
'`%s%s`',
32-
$this->aliasPrefix ? "{$this->aliasPrefix}." : '',
33+
$aliasPrefix,
3334
str_replace('`', '', $field),
3435
);
36+
} elseif($this->alias) {
37+
$alias = sprintf(
38+
'`%s%s`',
39+
$aliasPrefix,
40+
$this->alias,
41+
);
3542
}
3643
} else {
3744
$alias = $parts[1];
@@ -61,9 +68,9 @@ public function withAliasPrefix(?string $prefix = null): self
6168
return $this;
6269
}
6370

64-
public function withAlias(): self
71+
public function withAlias(bool|string $alias = true): self
6572
{
66-
$this->withAlias = true;
73+
$this->alias = $alias;
6774

6875
return $this;
6976
}

tests/Fixtures/Modules/Books/Models/Isbn.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
namespace Tests\Tempest\Fixtures\Modules\Books\Models;
44

5+
use Tempest\Database\IsDatabaseModel;
6+
57
final class Isbn
68
{
9+
use IsDatabaseModel;
10+
711
public string $value;
812

913
public Book $book;

tests/Integration/Database/Builder/SelectQueryBuilderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ public function test_with_belongs_to_relation(): void
313313
->build();
314314

315315
$this->assertSame(<<<SQL
316-
SELECT books.title AS `books.title`, books.author_id AS `books.author_id`, books.id AS `books.id`, authors.name AS `authors.name`, authors.type AS `authors.type`, authors.publisher_id AS `authors.publisher_id`, authors.id AS `authors.id`, chapters.title AS `chapters.title`, chapters.contents AS `chapters.contents`, chapters.book_id AS `chapters.book_id`, chapters.id AS `chapters.id`, isbns.value AS `isbns.value`, isbns.book_id AS `isbns.book_id`
316+
SELECT books.title AS `books.title`, books.author_id AS `books.author_id`, books.id AS `books.id`, authors.name AS `author.name`, authors.type AS `author.type`, authors.publisher_id AS `author.publisher_id`, authors.id AS `author.id`, chapters.title AS `chapters.title`, chapters.contents AS `chapters.contents`, chapters.book_id AS `chapters.book_id`, chapters.id AS `chapters.id`, isbns.value AS `isbn.value`, isbns.book_id AS `isbn.book_id`, isbns.id AS `isbn.id`
317317
FROM `books`
318318
LEFT JOIN authors ON authors.id = books.author_id
319319
LEFT JOIN chapters ON chapters.book_id = books.id

tests/Integration/Database/HasManyTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function test_has_many_with_parent(): void
7878
$relation = $model->getRelation('owners')->setParent('parent');
7979

8080
$this->assertSame(
81-
'owner.relation_id AS `parent.owner.relation_id`',
81+
'owner.relation_id AS `parent.owners.relation_id`',
8282
$relation->getSelectFields()[0]->compile(DatabaseDialect::SQLITE),
8383
);
8484
}

tests/Integration/ORM/IsDatabaseModelTest.php

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Tempest\Validation\Exceptions\ValidationException;
1717
use Tests\Tempest\Fixtures\Migrations\CreateAuthorTable;
1818
use Tests\Tempest\Fixtures\Migrations\CreateBookTable;
19+
use Tests\Tempest\Fixtures\Migrations\CreateChapterTable;
20+
use Tests\Tempest\Fixtures\Migrations\CreateIsbnTable;
1921
use Tests\Tempest\Fixtures\Migrations\CreatePublishersTable;
2022
use Tests\Tempest\Fixtures\Models\A;
2123
use Tests\Tempest\Fixtures\Models\AWithEager;
@@ -27,6 +29,7 @@
2729
use Tests\Tempest\Fixtures\Modules\Books\Models\Author;
2830
use Tests\Tempest\Fixtures\Modules\Books\Models\AuthorType;
2931
use Tests\Tempest\Fixtures\Modules\Books\Models\Book;
32+
use Tests\Tempest\Fixtures\Modules\Books\Models\Isbn;
3033
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
3134
use Tests\Tempest\Integration\ORM\Migrations\CreateATable;
3235
use Tests\Tempest\Integration\ORM\Migrations\CreateBTable;
@@ -296,41 +299,36 @@ public function test_empty_has_many_relation(): void
296299
{
297300
$this->migrate(
298301
CreateMigrationsTable::class,
299-
CreateHasManyParentTable::class,
302+
CreatePublishersTable::class,
303+
CreateAuthorTable::class,
304+
CreateBookTable::class,
305+
CreateChapterTable::class,
300306
CreateHasManyChildTable::class,
301-
CreateHasManyThroughTable::class,
302307
);
303308

304-
$parent = new ParentModel(name: 'parent')->save();
305-
306-
$parent = ParentModel::select()->with('through.child')->get($parent->id);
307-
308-
$this->assertInstanceOf(ParentModel::class, $parent);
309-
$this->assertEmpty($parent->through);
309+
Book::new(title: 'Timeline Taxi')->save();
310+
$book = Book::select()->with('chapters')->first();
311+
$this->assertEmpty($book->chapters);
310312
}
311313

312314
public function test_has_one_relation(): void
313315
{
314316
$this->migrate(
315317
CreateMigrationsTable::class,
316-
CreateHasManyParentTable::class,
318+
CreatePublishersTable::class,
319+
CreateAuthorTable::class,
320+
CreateBookTable::class,
321+
CreateChapterTable::class,
317322
CreateHasManyChildTable::class,
318-
CreateHasManyThroughTable::class,
323+
CreateIsbnTable::class,
319324
);
320325

321-
$parent = new ParentModel(name: 'parent')->save();
322-
$childA = new ChildModel(name: 'A')->save();
323-
$childB = new ChildModel(name: 'B')->save();
324-
325-
new ThroughModel(parent: $parent, child: $childA, child2: $childB)->save();
326+
$book = Book::new(title: 'Timeline Taxi')->save();
327+
$isbn = Isbn::new(value: 'tt-1', book: $book)->save();
326328

327-
$child = ChildModel::select()->with('through.parent')->get($childA->id);
329+
$isbn = Isbn::select()->with('book')->get($isbn->id);
328330

329-
$this->assertSame('parent', $child->through->parent->name);
330-
331-
$child2 = ChildModel::select()->with('through2.parent')->get($childB->id);
332-
333-
$this->assertSame('parent', $child2->through2->parent->name);
331+
$this->assertSame('Timeline Taxi', $isbn->book->title);
334332
}
335333

336334
public function test_invalid_has_one_relation(): void
@@ -345,15 +343,14 @@ public function test_invalid_has_one_relation(): void
345343
$parent = new ParentModel(name: 'parent')->save();
346344

347345
$childA = new ChildModel(name: 'A')->save();
348-
349346
$childB = new ChildModel(name: 'B')->save();
350347

351348
new ThroughModel(parent: $parent, child: $childA, child2: $childB)->save();
352349

353350
$child = ChildModel::get($childA->id, ['through.parent']);
354-
$child2 = ChildModel::get($childB->id, ['through2.parent']);
355-
356351
$this->assertSame('parent', $child->through->parent->name);
352+
353+
$child2 = ChildModel::select()->with('through2.parent')->get($childB->id);
357354
$this->assertSame('parent', $child2->through2->parent->name);
358355
}
359356

0 commit comments

Comments
 (0)