Skip to content

Commit 3507b43

Browse files
committed
Preserve explicit stream values in binary cursor bindings
Explicit cursor parameters already support stream resources as LOB bindings. Reversing a binary attribute cast must not send those raw bytes through the readable UUID or ULID encoder, which rejects resource values. Normalize streams through BinaryParameter::fromStream before invoking the caster. Keep non-binary attributes unchanged and preserve native conversion errors for malformed readable values. Extend the existing explicit-cursor regression while retaining binary-wrapper, encoded-cursor and source-alias coverage without duplicate execution. The regression reproduces the resource TypeError before the correction. The complete binary and cursor integration suites pass on SQLite, PostgreSQL, MySQL and MariaDB; formatting and complete static analysis also pass.
1 parent f287863 commit 3507b43

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

‎src/database/src/Eloquent/Concerns/HasAttributes.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,13 +1980,19 @@ public function prepareBinaryAttributesForDatabase(array $attributes): array
19801980

19811981
/**
19821982
* Encode a binary attribute's cast value, such as a UUID string, for database binding.
1983+
*
1984+
* Preserve explicit binary parameters and raw streams without encoding them again.
19831985
*/
19841986
public function encodeBinaryAttributeForDatabase(string $key, mixed $value): mixed
19851987
{
19861988
if ($value instanceof BinaryParameter || ! $this->isBinaryCast($this->getCasts()[$key] ?? null)) {
19871989
return $value;
19881990
}
19891991

1992+
if (is_resource($value)) {
1993+
return BinaryParameter::fromStream($value);
1994+
}
1995+
19901996
$bytes = $this->resolveCasterClass($key)->set($this, $key, $value, $this->attributes)[$key];
19911997

19921998
return is_string($bytes) ? new BinaryParameter($bytes) : $bytes;

‎tests/Integration/Database/DatabaseEloquentAsBinaryIntegrationTest.php‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,24 @@ public function testBinaryPrimaryKeysCanBeCursorPaginatedInBothDirections(bool $
255255
AsBinaryPrimaryKeyModel::create(['id' => $id, 'name' => $id]);
256256
}
257257

258-
$explicit = AsBinaryPrimaryKeyModel::query()->orderBy('id')->cursorPaginate(2, cursor: new Cursor([
259-
'id' => new BinaryParameter(Uuid::fromString($ids[1])->toBinary()),
260-
]));
261-
$this->assertSame([$ids[2]], $explicit->pluck('id')->all());
258+
if (! $aliased) {
259+
$bytes = Uuid::fromString($ids[1])->toBinary();
260+
$stream = fopen('php://memory', 'w+');
261+
262+
try {
263+
fwrite($stream, $bytes);
264+
rewind($stream);
265+
266+
foreach ([new BinaryParameter($bytes), $stream] as $parameter) {
267+
$explicit = AsBinaryPrimaryKeyModel::query()->orderBy('id')
268+
->cursorPaginate(2, cursor: new Cursor(['id' => $parameter]));
269+
270+
$this->assertSame([$ids[2]], $explicit->pluck('id')->all());
271+
}
272+
} finally {
273+
fclose($stream);
274+
}
275+
}
262276

263277
$query = fn () => $aliased
264278
? AsBinaryPrimaryKeyModel::query()->from('binary_primary_keys as identifiers')->orderBy('identifiers.id')

0 commit comments

Comments
 (0)