Skip to content

Commit b08bd8e

Browse files
committed
Make lazy BSON classes serializable
1 parent 3426ce1 commit b08bd8e

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

src/Model/LazyBSONArray.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,36 @@ public function __construct($input = null, ?CodecLibrary $codecLibrary = null)
109109
$this->codecLibrary = $codecLibrary ?? new LazyBSONCodecLibrary();
110110
}
111111

112+
/** @return array{bson: PackedArray<TValue>, set: array<int, TValue>, unset: array<int, true>, codecLibrary: CodecLibrary} */
113+
public function __serialize(): array
114+
{
115+
return [
116+
'bson' => $this->bson,
117+
'set' => $this->set,
118+
'unset' => $this->unset,
119+
'codecLibrary' => $this->codecLibrary,
120+
];
121+
}
122+
123+
/** @param array{bson: PackedArray<TValue>, set: array<int, TValue>, unset: array<int, true>, codecLibrary: CodecLibrary} $data */
124+
public function __unserialize(array $data): void
125+
{
126+
$this->bson = $data['bson'];
127+
$this->set = $data['set'];
128+
$this->unset = $data['unset'];
129+
$this->codecLibrary = $data['codecLibrary'];
130+
131+
$this->exists = array_map(
132+
/** @param TValue $value */
133+
fn ($value): bool => true,
134+
$this->set,
135+
);
136+
137+
foreach ($this->unset as $index => $unused) {
138+
$this->exists[$index] = false;
139+
}
140+
}
141+
112142
public function count(): int
113143
{
114144
$this->readEntirePackedArray();

src/Model/LazyBSONDocument.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
use function array_filter;
3434
use function array_key_exists;
35+
use function array_map;
3536
use function count;
3637
use function get_object_vars;
3738
use function is_array;
@@ -130,6 +131,17 @@ public function __isset(string $name): bool
130131
return $this->exists[$name] ??= $this->bson->has($name);
131132
}
132133

134+
/** @return array{bson: Document<TValue>, set: array<string, TValue>, unset: array<string, true>, codecLibrary: CodecLibrary} */
135+
public function __serialize(): array
136+
{
137+
return [
138+
'bson' => $this->bson,
139+
'set' => $this->set,
140+
'unset' => $this->unset,
141+
'codecLibrary' => $this->codecLibrary,
142+
];
143+
}
144+
133145
/** @param TValue $value */
134146
public function __set(string $property, $value): void
135147
{
@@ -138,6 +150,25 @@ public function __set(string $property, $value): void
138150
$this->exists[$property] = true;
139151
}
140152

153+
/** @param array{bson: Document<TValue>, set: array<string, TValue>, unset: array<string, true>, codecLibrary: CodecLibrary} $data */
154+
public function __unserialize(array $data): void
155+
{
156+
$this->bson = $data['bson'];
157+
$this->set = $data['set'];
158+
$this->unset = $data['unset'];
159+
$this->codecLibrary = $data['codecLibrary'];
160+
161+
$this->exists = array_map(
162+
/** @param TValue $value */
163+
fn ($value): bool => true,
164+
$this->set,
165+
);
166+
167+
foreach ($this->unset as $name => $unused) {
168+
$this->exists[$name] = false;
169+
}
170+
}
171+
141172
public function __unset(string $name): void
142173
{
143174
$this->unset[$name] = true;

tests/Model/LazyBSONArrayTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use stdClass;
1212

1313
use function iterator_to_array;
14+
use function serialize;
15+
use function unserialize;
1416

1517
class LazyBSONArrayTest extends TestCase
1618
{
@@ -258,4 +260,17 @@ public function testCount(): void
258260
$array[] = 'yay';
259261
$this->assertCount(3, $array);
260262
}
263+
264+
public function testSerialization(): void
265+
{
266+
$array = new LazyBSONArray(PackedArray::fromPHP(['foo', 'bar', 'baz']));
267+
$array[0] = 'foobar';
268+
$array[3] = 'yay!';
269+
unset($array[1]);
270+
271+
$serialized = serialize($array);
272+
$unserialized = unserialize($serialized);
273+
274+
$this->assertEquals(['foobar', 'baz', 'yay!'], iterator_to_array($unserialized));
275+
}
261276
}

tests/Model/LazyBSONDocumentTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use stdClass;
1212

1313
use function iterator_to_array;
14+
use function serialize;
15+
use function unserialize;
1416

1517
class LazyBSONDocumentTest extends TestCase
1618
{
@@ -308,4 +310,17 @@ public function testCount(): void
308310
$document['baz'] = 'yay';
309311
$this->assertCount(2, $document);
310312
}
313+
314+
public function testSerialization(): void
315+
{
316+
$document = new LazyBSONDocument(Document::fromPHP(['foo' => 'bar', 'bar' => 'baz']));
317+
$document['foo'] = 'foobar';
318+
$document['baz'] = 'yay!';
319+
unset($document['bar']);
320+
321+
$serialized = serialize($document);
322+
$unserialized = unserialize($serialized);
323+
324+
$this->assertEquals(['foo' => 'foobar', 'baz' => 'yay!'], iterator_to_array($unserialized));
325+
}
311326
}

0 commit comments

Comments
 (0)