Skip to content

Commit b1aba5c

Browse files
committed
fix(database): support virtual properties
Closes #1474
1 parent e801057 commit b1aba5c

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Tempest\Database\PrimaryKey;
1313
use Tempest\Database\Query;
1414
use Tempest\Database\QueryStatements\InsertStatement;
15+
use Tempest\Database\Virtual;
1516
use Tempest\Intl;
1617
use Tempest\Mapper\SerializerFactory;
1718
use Tempest\Reflection\ClassReflector;
@@ -390,6 +391,11 @@ private function resolveObjectData(object $model): array
390391
}
391392

392393
$propertyName = $property->getName();
394+
395+
if ($property->hasAttribute(Virtual::class)) {
396+
continue;
397+
}
398+
393399
$value = $property->getValue($model);
394400

395401
if ($definition->getHasMany($propertyName)) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Tempest\Database\QueryStatements\HasWhereStatements;
1515
use Tempest\Database\QueryStatements\UpdateStatement;
1616
use Tempest\Database\QueryStatements\WhereStatement;
17+
use Tempest\Database\Virtual;
1718
use Tempest\Intl;
1819
use Tempest\Mapper\SerializerFactory;
1920
use Tempest\Reflection\ClassReflector;
@@ -473,6 +474,10 @@ private function convertObjectToArray(object $object): array
473474
$reflection = new ClassReflector($object);
474475

475476
foreach ($reflection->getPublicProperties() as $property) {
477+
if ($property->hasAttribute(Virtual::class)) {
478+
continue;
479+
}
480+
476481
if ($property->isInitialized($object)) {
477482
$result[$property->getName()] = $property->getValue($object);
478483
}

packages/database/src/IsDatabaseModel.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Tempest\Database\Builder\QueryBuilders\SelectQueryBuilder;
1010
use Tempest\Database\Exceptions\RelationWasMissing;
1111
use Tempest\Database\Exceptions\ValueWasMissing;
12+
use Tempest\Database\Virtual;
1213
use Tempest\Reflection\ClassReflector;
1314
use Tempest\Reflection\PropertyReflector;
1415

@@ -175,6 +176,10 @@ public function refresh(): self
175176
$refreshed = self::find(id: $primaryKeyValue)->first();
176177

177178
foreach (new ClassReflector($refreshed)->getPublicProperties() as $property) {
179+
if ($property->hasAttribute(Virtual::class)) {
180+
continue;
181+
}
182+
178183
$property->setValue($this, $property->getValue($refreshed));
179184
}
180185

@@ -198,6 +203,10 @@ public function load(string ...$relations): self
198203
$new = self::get($primaryKeyValue, $relations);
199204

200205
foreach (new ClassReflector($new)->getPublicProperties() as $property) {
206+
if ($property->hasAttribute(Virtual::class)) {
207+
continue;
208+
}
209+
201210
$property->setValue($this, $property->getValue($new));
202211
}
203212

packages/database/src/Virtual.php

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

77
use Attribute;
88

9+
/**
10+
* Virtual properties are ignored by the database mapper.
11+
*/
912
#[Attribute(Attribute::TARGET_PROPERTY)]
1013
final readonly class Virtual
1114
{

tests/Integration/Database/Builder/IsDatabaseModelTest.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,25 @@ public function test_no_result(): void
433433
$this->assertNull(A::select()->first());
434434
}
435435

436-
public function test_virtual_property(): void
436+
public function test_create_with_virtual_property(): void
437+
{
438+
$this->migrate(
439+
CreateMigrationsTable::class,
440+
CreateATable::class,
441+
CreateBTable::class,
442+
CreateCTable::class,
443+
);
444+
445+
$a = AWithVirtual::create(
446+
b: new B(
447+
c: new C(name: 'test'),
448+
),
449+
);
450+
451+
$this->assertSame(-$a->id->value, $a->fake);
452+
}
453+
454+
public function test_select_virtual_property(): void
437455
{
438456
$this->migrate(
439457
CreateMigrationsTable::class,
@@ -453,6 +471,36 @@ public function test_virtual_property(): void
453471
$this->assertSame(-$a->id->value, $a->fake);
454472
}
455473

474+
public function test_update_with_virtual_property(): void
475+
{
476+
$this->migrate(
477+
CreateMigrationsTable::class,
478+
CreateATable::class,
479+
CreateBTable::class,
480+
CreateCTable::class,
481+
);
482+
483+
$a = AWithVirtual::create(
484+
b: new B(
485+
c: new C(name: 'test'),
486+
),
487+
);
488+
489+
$a->update(
490+
b: new B(
491+
c: new C(name: 'updated'),
492+
),
493+
);
494+
495+
$updatedA = AWithVirtual::select()
496+
->with('b.c')
497+
->where('id', $a->id)
498+
->first();
499+
500+
$this->assertSame(-$updatedA->id->value, $updatedA->fake);
501+
$this->assertSame('updated', $updatedA->b->c->name);
502+
}
503+
456504
public function test_update_or_create(): void
457505
{
458506
$this->migrate(

0 commit comments

Comments
 (0)