From 7cacc559d2532eb247f1dddb589395d3784306ef Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 09:28:00 +0100 Subject: [PATCH 1/8] Cache relations in model inspector --- packages/database/src/Builder/ModelInspector.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index 59f9b6b64..45394f908 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -33,6 +33,8 @@ final class ModelInspector private(set) object|string $instance; + private static array $relations = []; + private Validator $validator { get => get(Validator::class); } @@ -263,6 +265,10 @@ public function getRelations(): ImmutableArray return arr(); } + if (isset(self::$relations[$this->getName()])) { + return self::$relations[$this->getName()]; + } + $relationFields = arr(); foreach ($this->reflector->getPublicProperties() as $property) { @@ -271,6 +277,8 @@ public function getRelations(): ImmutableArray } } + self::$relations[$this->getName()] = $relationFields; + return $relationFields; } From d47461c2e6c0786a6752313488355ae1d6ebaafe Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 10:01:43 +0100 Subject: [PATCH 2/8] Memoize mapper related results --- .../database/src/Builder/ModelInspector.php | 274 ++++++++++-------- packages/database/src/functions.php | 2 +- packages/mapper/src/CasterFactory.php | 56 ++-- .../src/Mappers/ArrayToObjectMapper.php | 17 +- packages/mapper/src/SerializerFactory.php | 49 ++-- packages/reflection/src/PropertyReflector.php | 5 + .../src/Memoization/HasMemoization.php | 19 ++ 7 files changed, 243 insertions(+), 179 deletions(-) create mode 100644 packages/support/src/Memoization/HasMemoization.php diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index 45394f908..eaa09732e 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -18,6 +18,7 @@ use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; use Tempest\Support\Arr\ImmutableArray; +use Tempest\Support\Memoization\HasMemoization; use Tempest\Validation\Exceptions\ValidationFailed; use Tempest\Validation\SkipValidation; use Tempest\Validation\Validator; @@ -29,16 +30,25 @@ final class ModelInspector { + use HasMemoization; + + private static array $inspectors = []; + private(set) ?ClassReflector $reflector; private(set) object|string $instance; - private static array $relations = []; - private Validator $validator { get => get(Validator::class); } + public static function forModel(object|string $model): self + { + $key = is_object($model) ? get_class($model) : $model; + + return self::$inspectors[$key] ??= new self($model); + } + public function __construct( private(set) object|string $model, ) { @@ -68,27 +78,31 @@ public function isObjectModel(): bool public function getTableDefinition(): TableDefinition { - if (! $this->isObjectModel()) { - return new TableDefinition($this->instance); - } + return $this->memoize('getTableDefinition', function () { + if (! $this->isObjectModel()) { + return new TableDefinition($this->instance); + } - $specificName = $this->reflector - ->getAttribute(Table::class) - ?->name; + $specificName = $this->reflector + ->getAttribute(Table::class) + ?->name; - $conventionalName = get(DatabaseConfig::class) - ->namingStrategy - ->getName($this->reflector->getName()); + $conventionalName = get(DatabaseConfig::class) + ->namingStrategy + ->getName($this->reflector->getName()); - return new TableDefinition($specificName ?? $conventionalName); + return new TableDefinition($specificName ?? $conventionalName); + }); } public function getFieldDefinition(string $field): FieldDefinition { - return new FieldDefinition( - $this->getTableDefinition(), - $field, - ); + return $this->memoize('getFieldDefinition' . $field, function () use ($field) { + return new FieldDefinition( + $this->getTableDefinition(), + $field, + ); + }); } public function getTableName(): string @@ -98,162 +112,174 @@ public function getTableName(): string public function getPropertyValues(): array { - if (! $this->isObjectModel()) { - return []; - } + return $this->memoize('getPropertyValues', function () { + if (! $this->isObjectModel()) { + return []; + } - if (! is_object($this->instance)) { - return []; - } + if (! is_object($this->instance)) { + return []; + } - $values = []; + $values = []; - foreach ($this->reflector->getProperties() as $property) { - if ($property->isVirtual()) { - continue; - } + foreach ($this->reflector->getProperties() as $property) { + if ($property->isVirtual()) { + continue; + } - if ($property->hasAttribute(Virtual::class)) { - continue; - } + if ($property->hasAttribute(Virtual::class)) { + continue; + } - if (! $property->isInitialized($this->instance)) { - continue; - } + if (! $property->isInitialized($this->instance)) { + continue; + } - if ($this->getHasMany($property->getName()) || $this->getHasOne($property->getName())) { - continue; - } + if ($this->getHasMany($property->getName()) || $this->getHasOne($property->getName())) { + continue; + } - $name = $property->getName(); + $name = $property->getName(); - $values[$name] = $property->getValue($this->instance); - } + $values[$name] = $property->getValue($this->instance); + } - return $values; + return $values; + }); } public function getBelongsTo(string $name): ?BelongsTo { - if (! $this->isObjectModel()) { - return null; - } + return $this->memoize('getBelongsTo' . $name, function () use ($name) { + if (! $this->isObjectModel()) { + return null; + } - $name = str($name)->camel(); + $name = str($name)->camel(); - $singularizedName = $name->singularizeLastWord(); + $singularizedName = $name->singularizeLastWord(); - if (! $singularizedName->equals($name)) { - return $this->getBelongsTo($singularizedName); - } + if (! $singularizedName->equals($name)) { + return $this->getBelongsTo($singularizedName); + } - if (! $this->reflector->hasProperty($name)) { - return null; - } + if (! $this->reflector->hasProperty($name)) { + return null; + } - $property = $this->reflector->getProperty($name); + $property = $this->reflector->getProperty($name); - if ($belongsTo = $property->getAttribute(BelongsTo::class)) { - return $belongsTo; - } + if ($belongsTo = $property->getAttribute(BelongsTo::class)) { + return $belongsTo; + } - if ($property->hasAttribute(Virtual::class)) { - return null; - } + if ($property->hasAttribute(Virtual::class)) { + return null; + } - if (! $property->getType()->isRelation()) { - return null; - } + if (! $property->getType()->isRelation()) { + return null; + } - if ($property->hasAttribute(SerializeWith::class) || $property->getType()->asClass()->hasAttribute(SerializeWith::class)) { - return null; - } + if ($property->hasAttribute(SerializeWith::class) || $property->getType()->asClass()->hasAttribute(SerializeWith::class)) { + return null; + } - if ($property->getType()->asClass()->hasAttribute(SerializeAs::class)) { - return null; - } + if ($property->getType()->asClass()->hasAttribute(SerializeAs::class)) { + return null; + } - if ($property->hasAttribute(HasOne::class)) { - return null; - } + if ($property->hasAttribute(HasOne::class)) { + return null; + } - $belongsTo = new BelongsTo(); - $belongsTo->property = $property; + $belongsTo = new BelongsTo(); + $belongsTo->property = $property; - return $belongsTo; + return $belongsTo; + }); } public function getHasOne(string $name): ?HasOne { - if (! $this->isObjectModel()) { - return null; - } + return $this->memoize('getHasOne' . $name, function () use ($name) { + if (! $this->isObjectModel()) { + return null; + } - $name = str($name)->camel(); + $name = str($name)->camel(); - $singularizedName = $name->singularizeLastWord(); + $singularizedName = $name->singularizeLastWord(); - if (! $singularizedName->equals($name)) { - return $this->getHasOne($singularizedName); - } + if (! $singularizedName->equals($name)) { + return $this->getHasOne($singularizedName); + } - if (! $this->reflector->hasProperty($name)) { - return null; - } + if (! $this->reflector->hasProperty($name)) { + return null; + } - $property = $this->reflector->getProperty($name); + $property = $this->reflector->getProperty($name); - if ($hasOne = $property->getAttribute(HasOne::class)) { - return $hasOne; - } + if ($hasOne = $property->getAttribute(HasOne::class)) { + return $hasOne; + } - return null; + return null; + }); } public function getHasMany(string $name): ?HasMany { - if (! $this->isObjectModel()) { - return null; - } + return $this->memoize('getHasMany' . $name, function () use ($name) { + if (! $this->isObjectModel()) { + return null; + } - $name = str($name)->camel(); + $name = str($name)->camel(); - if (! $this->reflector->hasProperty($name)) { - return null; - } + if (! $this->reflector->hasProperty($name)) { + return null; + } - $property = $this->reflector->getProperty($name); + $property = $this->reflector->getProperty($name); - if ($hasMany = $property->getAttribute(HasMany::class)) { - return $hasMany; - } + if ($hasMany = $property->getAttribute(HasMany::class)) { + return $hasMany; + } - if ($property->hasAttribute(Virtual::class)) { - return null; - } + if ($property->hasAttribute(Virtual::class)) { + return null; + } - if (! $property->getIterableType()?->isRelation()) { - return null; - } + if (! $property->getIterableType()?->isRelation()) { + return null; + } - $hasMany = new HasMany(); - $hasMany->property = $property; + $hasMany = new HasMany(); + $hasMany->property = $property; - return $hasMany; + return $hasMany; + }); } public function isRelation(string|PropertyReflector $name): bool { $name = $name instanceof PropertyReflector ? $name->getName() : $name; - return $this->getBelongsTo($name) !== null || $this->getHasOne($name) !== null || $this->getHasMany($name) !== null; + return $this->memoize('isRelation' . $name, function () use ($name) { + return $this->getBelongsTo($name) !== null || $this->getHasOne($name) !== null || $this->getHasMany($name) !== null; + }); } public function getRelation(string|PropertyReflector $name): ?Relation { $name = $name instanceof PropertyReflector ? $name->getName() : $name; - return $this->getBelongsTo($name) ?? $this->getHasOne($name) ?? $this->getHasMany($name); + return $this->memoize('getRelation' . $name, function () use ($name) { + return $this->getBelongsTo($name) ?? $this->getHasOne($name) ?? $this->getHasMany($name); + }); } /** @@ -261,25 +287,21 @@ public function getRelation(string|PropertyReflector $name): ?Relation */ public function getRelations(): ImmutableArray { - if (! $this->isObjectModel()) { - return arr(); - } - - if (isset(self::$relations[$this->getName()])) { - return self::$relations[$this->getName()]; - } + return $this->memoize('getRelations', function () { + if (! $this->isObjectModel()) { + return arr(); + } - $relationFields = arr(); + $relationFields = arr(); - foreach ($this->reflector->getPublicProperties() as $property) { - if ($relation = $this->getRelation($property->getName())) { - $relationFields[] = $relation; + foreach ($this->reflector->getPublicProperties() as $property) { + if ($relation = $this->getRelation($property->getName())) { + $relationFields[] = $relation; + } } - } - - self::$relations[$this->getName()] = $relationFields; - return $relationFields; + return $relationFields; + }); } /** diff --git a/packages/database/src/functions.php b/packages/database/src/functions.php index c635c96ef..af93d2bc9 100644 --- a/packages/database/src/functions.php +++ b/packages/database/src/functions.php @@ -26,6 +26,6 @@ function query(string|object $model): QueryBuilder */ function inspect(string|object $model): ModelInspector { - return new ModelInspector($model); + return ModelInspector::forModel($model); } } diff --git a/packages/mapper/src/CasterFactory.php b/packages/mapper/src/CasterFactory.php index 9151ba185..3e5c7dd3e 100644 --- a/packages/mapper/src/CasterFactory.php +++ b/packages/mapper/src/CasterFactory.php @@ -8,11 +8,14 @@ use Tempest\Container\Container; use Tempest\Container\Singleton; use Tempest\Reflection\PropertyReflector; +use Tempest\Support\Memoization\HasMemoization; use UnitEnum; #[Singleton] final class CasterFactory { + use HasMemoization; + /** * @var array, int}[]> */ @@ -44,45 +47,48 @@ public function addCaster(string $casterClass, int $priority = 0, Context|UnitEn */ public function in(Context|UnitEnum|string $context): self { - $serializer = clone $this; - $serializer->context = $context; + $caster = clone $this; + $caster->context = $context; - return $serializer; + return $caster; } public function forProperty(PropertyReflector $property): ?Caster { $context = MappingContext::from($this->context); - $type = $property->getType(); - $castWith = $property->getAttribute(CastWith::class); - - if ($castWith === null && $type->isClass()) { - $castWith = $type->asClass()->getAttribute(CastWith::class, recursive: true); - } - if ($castWith) { - return $this->container->get($castWith->className, context: $context); - } + return $this->memoize('[' . $context->name . '] ' . $property->getName(), function () use ($property, $context) { + $type = $property->getType(); + $castWith = $property->getAttribute(CastWith::class); - if ($casterAttribute = $property->getAttribute(ProvidesCaster::class)) { - return $this->container->get($casterAttribute->caster, context: $context); - } + if ($castWith === null && $type->isClass()) { + $castWith = $type->asClass()->getAttribute(CastWith::class, recursive: true); + } - foreach ($this->resolveCasters() as [$casterClass]) { - if (is_a($casterClass, DynamicCaster::class, allow_string: true)) { - if (! $casterClass::accepts($property)) { - continue; - } + if ($castWith) { + return $this->container->get($castWith->className, context: $context); } - if (is_a($casterClass, ConfigurableCaster::class, allow_string: true)) { - return $casterClass::configure($property, $context); + if ($casterAttribute = $property->getAttribute(ProvidesCaster::class)) { + return $this->container->get($casterAttribute->caster, context: $context); } - return $this->container->get($casterClass, context: $context); - } + foreach ($this->resolveCasters() as [$casterClass]) { + if (is_a($casterClass, DynamicCaster::class, allow_string: true)) { + if (! $casterClass::accepts($property)) { + continue; + } + } + + if (is_a($casterClass, ConfigurableCaster::class, allow_string: true)) { + return $casterClass::configure($property, $context); + } + + return $this->container->get($casterClass, context: $context); + } - return null; + return null; + }); } /** diff --git a/packages/mapper/src/Mappers/ArrayToObjectMapper.php b/packages/mapper/src/Mappers/ArrayToObjectMapper.php index af1bd9395..7694cfee9 100644 --- a/packages/mapper/src/Mappers/ArrayToObjectMapper.php +++ b/packages/mapper/src/Mappers/ArrayToObjectMapper.php @@ -13,15 +13,18 @@ use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; use Tempest\Support\Arr; +use Tempest\Support\Memoization\HasMemoization; use Throwable; use function Tempest\Support\arr; -final readonly class ArrayToObjectMapper implements Mapper +final class ArrayToObjectMapper implements Mapper { + use HasMemoization; + public function __construct( - private CasterFactory $casterFactory, - private Context $context, + private readonly CasterFactory $casterFactory, + private readonly Context $context, ) {} public function canMap(mixed $from, mixed $to): bool @@ -158,9 +161,11 @@ private function setChildParentRelation(object $parent, mixed $child, ClassRefle public function resolveValue(PropertyReflector $property, mixed $value): mixed { - $caster = $this->casterFactory - ->in($this->context) - ->forProperty($property); + $caster = $this->memoize((string) $property, function () use ($property, $value) { + return $this->casterFactory + ->in($this->context) + ->forProperty($property); + }); if ($property->isNullable() && $value === null) { return null; diff --git a/packages/mapper/src/SerializerFactory.php b/packages/mapper/src/SerializerFactory.php index 645c068f5..d82f19ffa 100644 --- a/packages/mapper/src/SerializerFactory.php +++ b/packages/mapper/src/SerializerFactory.php @@ -10,11 +10,14 @@ use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; use Tempest\Reflection\TypeReflector; +use Tempest\Support\Memoization\HasMemoization; use UnitEnum; #[Singleton] final class SerializerFactory { + use HasMemoization; + /** * @var array,int}[]> */ @@ -55,36 +58,40 @@ public function in(Context|UnitEnum|string $context): self public function forProperty(PropertyReflector $property): ?Serializer { $context = MappingContext::from($this->context); - $type = $property->getType(); - $serializeWith = $property->getAttribute(SerializeWith::class); - if ($serializeWith === null && $type->isClass()) { - $serializeWith = $type->asClass()->getAttribute(SerializeWith::class, recursive: true); - } + return $this->memoize('[' . $context->name . '] ' . $property->getName(), function () use ($property, $context) { + $context = MappingContext::from($this->context); + $type = $property->getType(); + $serializeWith = $property->getAttribute(SerializeWith::class); - if ($serializeWith !== null) { - return $this->container->get($serializeWith->className, context: $context); - } + if ($serializeWith === null && $type->isClass()) { + $serializeWith = $type->asClass()->getAttribute(SerializeWith::class, recursive: true); + } - if ($serializerAttribute = $property->getAttribute(ProvidesSerializer::class)) { - return $this->container->get($serializerAttribute->serializer, context: $context); - } + if ($serializeWith !== null) { + return $this->container->get($serializeWith->className, context: $context); + } - foreach ($this->resolveSerializers() as [$serializerClass]) { - if (is_a($serializerClass, DynamicSerializer::class, allow_string: true)) { - if (! $serializerClass::accepts($property)) { - continue; - } + if ($serializerAttribute = $property->getAttribute(ProvidesSerializer::class)) { + return $this->container->get($serializerAttribute->serializer, context: $context); } - $serializer = $this->resolveSerializer($serializerClass, $property); + foreach ($this->resolveSerializers() as [$serializerClass]) { + if (is_a($serializerClass, DynamicSerializer::class, allow_string: true)) { + if (! $serializerClass::accepts($property)) { + continue; + } + } - if ($serializer !== null) { - return $serializer; + $serializer = $this->resolveSerializer($serializerClass, $property); + + if ($serializer !== null) { + return $serializer; + } } - } - return null; + return null; + }); } public function forValue(mixed $value): ?Serializer diff --git a/packages/reflection/src/PropertyReflector.php b/packages/reflection/src/PropertyReflector.php index 455d8c898..3eda1ce13 100644 --- a/packages/reflection/src/PropertyReflector.php +++ b/packages/reflection/src/PropertyReflector.php @@ -157,4 +157,9 @@ public function hasDefaultValue(): bool return $hasDefaultValue || $hasPromotedDefaultValue; } + + public function __toString(): string + { + return $this->getClass()->getName() . '::' . $this->getName(); + } } diff --git a/packages/support/src/Memoization/HasMemoization.php b/packages/support/src/Memoization/HasMemoization.php new file mode 100644 index 000000000..cca26ef69 --- /dev/null +++ b/packages/support/src/Memoization/HasMemoization.php @@ -0,0 +1,19 @@ +memoize)) { + $this->memoize[$key] = $closure(); + } + + return $this->memoize[$key]; + } +} From f084b5c2867d22e17bb6c9caa701764284ed1726 Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 10:22:51 +0100 Subject: [PATCH 3/8] wip --- packages/database/src/Builder/ModelInspector.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index eaa09732e..0c9ece8bc 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -44,7 +44,13 @@ final class ModelInspector public static function forModel(object|string $model): self { - $key = is_object($model) ? get_class($model) : $model; + $key = match(true) { + is_string($model) => $model, + $model instanceof HasMany => $model->property->getIterableType()->getName(), + $model instanceof BelongsTo => $model->property->getType()->getName(), + $model instanceof HasOne => $model->property->getType()->getName(), + default => $model::class, + }; return self::$inspectors[$key] ??= new self($model); } From b14f4707ad4611907c53bd0ba15c373b1f4bc8a8 Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 10:24:05 +0100 Subject: [PATCH 4/8] wip --- packages/database/src/Builder/ModelInspector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index 0c9ece8bc..d0896ace1 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -44,7 +44,7 @@ final class ModelInspector public static function forModel(object|string $model): self { - $key = match(true) { + $key = match (true) { is_string($model) => $model, $model instanceof HasMany => $model->property->getIterableType()->getName(), $model instanceof BelongsTo => $model->property->getType()->getName(), From 5944528f301817b115005862351add64a627fcfb Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 10:56:23 +0100 Subject: [PATCH 5/8] wip --- packages/database/src/Builder/ModelInspector.php | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index d0896ace1..6da451fce 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -49,6 +49,7 @@ public static function forModel(object|string $model): self $model instanceof HasMany => $model->property->getIterableType()->getName(), $model instanceof BelongsTo => $model->property->getType()->getName(), $model instanceof HasOne => $model->property->getType()->getName(), + $model instanceof ClassReflector => $model->getName(), default => $model::class, }; From a8ebc43f2b2f2eb078e93bae07070a0ec55196ac Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 11:11:36 +0100 Subject: [PATCH 6/8] wip --- packages/database/src/Builder/ModelInspector.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index 6da451fce..c23668114 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -50,9 +50,13 @@ public static function forModel(object|string $model): self $model instanceof BelongsTo => $model->property->getType()->getName(), $model instanceof HasOne => $model->property->getType()->getName(), $model instanceof ClassReflector => $model->getName(), - default => $model::class, + default => null, }; + if ($key === null) { + return new self($model); + } + return self::$inspectors[$key] ??= new self($model); } From f10ecc290b06fc6fcfc4924e7e769fd538f10821 Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 11:22:08 +0100 Subject: [PATCH 7/8] wip --- packages/database/src/Builder/ModelInspector.php | 16 ++++++++++------ .../Integration/FrameworkIntegrationTestCase.php | 3 +++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index c23668114..a577aaffb 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -34,14 +34,19 @@ final class ModelInspector private static array $inspectors = []; - private(set) ?ClassReflector $reflector; + private(set) ClassReflector|null $reflector = null; - private(set) object|string $instance; + private(set) object|string|null $instance = null; private Validator $validator { get => get(Validator::class); } + public static function reset(): void + { + self::$inspectors = []; + } + public static function forModel(object|string $model): self { $key = match (true) { @@ -74,12 +79,11 @@ public function __construct( } else { try { $this->reflector = new ClassReflector($model); + $this->instance = $model; } catch (ReflectionException) { $this->reflector = null; } } - - $this->instance = $model; } public function isObjectModel(): bool @@ -91,7 +95,7 @@ public function getTableDefinition(): TableDefinition { return $this->memoize('getTableDefinition', function () { if (! $this->isObjectModel()) { - return new TableDefinition($this->instance); + return new TableDefinition($this->model); } $specificName = $this->reflector @@ -532,7 +536,7 @@ public function getName(): string return $this->reflector->getName(); } - return $this->instance; + return $this->model; } public function getQualifiedPrimaryKey(): ?string diff --git a/tests/Integration/FrameworkIntegrationTestCase.php b/tests/Integration/FrameworkIntegrationTestCase.php index 61ba1657f..4dda31142 100644 --- a/tests/Integration/FrameworkIntegrationTestCase.php +++ b/tests/Integration/FrameworkIntegrationTestCase.php @@ -6,6 +6,7 @@ use InvalidArgumentException; use Stringable; +use Tempest\Database\Builder\ModelInspector; use Tempest\Database\DatabaseInitializer; use Tempest\Discovery\DiscoveryLocation; use Tempest\Framework\Testing\IntegrationTest; @@ -54,6 +55,8 @@ protected function setUp(): void $this->container->config(require $databaseConfigPath); $this->database->reset(migrate: false); + + ModelInspector::reset(); } protected function render(string|View $view, mixed ...$params): string From fa741c3b2959d3f45248eb815046336e19bfd746 Mon Sep 17 00:00:00 2001 From: brendt Date: Wed, 7 Jan 2026 11:24:01 +0100 Subject: [PATCH 8/8] wip --- packages/database/src/Builder/ModelInspector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index a577aaffb..5c7f76093 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -34,7 +34,7 @@ final class ModelInspector private static array $inspectors = []; - private(set) ClassReflector|null $reflector = null; + private(set) ?ClassReflector $reflector = null; private(set) object|string|null $instance = null;