Skip to content

Commit b7dbb7a

Browse files
committed
fix(database): support virtual properties
Closes #1474
1 parent 0479e70 commit b7dbb7a

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
@@ -432,7 +432,25 @@ public function test_no_result(): void
432432
$this->assertNull(A::select()->first());
433433
}
434434

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

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

0 commit comments

Comments
 (0)