Skip to content

Commit 23808c5

Browse files
committed
refactor
1 parent e36fbd9 commit 23808c5

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

system/Database/BaseConnection.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,17 +468,29 @@ private function castScalarValueForTypedProperty(mixed $value, array $types): mi
468468
private function getBuiltinPropertyTypesMap(array $properties): array
469469
{
470470
$className = static::class;
471+
$requested = array_fill_keys($properties, true);
471472

472473
if (! isset(self::$propertyBuiltinTypesCache[$className])) {
473474
self::$propertyBuiltinTypesCache[$className] = [];
475+
}
476+
477+
// Fill only the properties requested by this call that are not cached yet.
478+
$missing = array_diff_key($requested, self::$propertyBuiltinTypesCache[$className]);
474479

480+
if ($missing !== []) {
475481
$reflection = new ReflectionClass($className);
476482

477483
foreach ($reflection->getProperties() as $property) {
484+
$propertyName = $property->getName();
485+
486+
if (! isset($missing[$propertyName])) {
487+
continue;
488+
}
489+
478490
$type = $property->getType();
479491

480492
if (! $type instanceof ReflectionType) {
481-
self::$propertyBuiltinTypesCache[$className][$property->getName()] = [];
493+
self::$propertyBuiltinTypesCache[$className][$propertyName] = [];
482494

483495
continue;
484496
}
@@ -498,7 +510,12 @@ private function getBuiltinPropertyTypesMap(array $properties): array
498510
$builtinTypes[] = 'null';
499511
}
500512

501-
self::$propertyBuiltinTypesCache[$className][$property->getName()] = $builtinTypes;
513+
self::$propertyBuiltinTypesCache[$className][$propertyName] = $builtinTypes;
514+
}
515+
516+
// Untyped or unresolved properties are cached as empty to avoid re-reflecting them.
517+
foreach (array_keys($missing) as $propertyName) {
518+
self::$propertyBuiltinTypesCache[$className][$propertyName] ??= [];
502519
}
503520
}
504521

tests/system/Database/BaseConnectionTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,30 @@ public function getWithTrue(): int|true
187187
$this->assertTrue($db->getWithTrue());
188188
}
189189

190+
public function testCachesTypedPropertiesIncrementally(): void
191+
{
192+
$factory = fn (array $options) => new class ($options) extends MockConnection {
193+
protected ?int $synchronous = null;
194+
protected ?int $busyTimeout = null;
195+
196+
public function getSynchronous(): ?int
197+
{
198+
return $this->synchronous;
199+
}
200+
201+
public function getBusyTimeout(): ?int
202+
{
203+
return $this->busyTimeout;
204+
}
205+
};
206+
207+
$first = $factory([...$this->options, 'synchronous' => '1']);
208+
$second = $factory([...$this->options, 'busyTimeout' => '4000']);
209+
210+
$this->assertSame(1, $first->getSynchronous());
211+
$this->assertSame(4000, $second->getBusyTimeout());
212+
}
213+
190214
public function testInvalidStringValueForTypedPropertyThrowsTypeError(): void
191215
{
192216
$this->expectException(TypeError::class);

0 commit comments

Comments
 (0)