-
Notifications
You must be signed in to change notification settings - Fork 266
PHPLIB-1181: Introduce lazy BSON classes #1135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
9064c9d
Add AsListIterator to remove gaps in arrays
alcaeus a214d58
Add lazy models for BSON documents and arrays
alcaeus f9fefe4
Introduce codecs to work with lazy BSON objects
alcaeus 01fcf4b
Remove assert for keys and use get_object_vars when building LazyBSON…
alcaeus ffedb9a
Use null-coalesce assignments
alcaeus 2b92818
Only support string offsets for LazyBSONDocument
alcaeus ddd75fe
Use object in LazyBSONCodecLibrary test
alcaeus 18a5f2a
Remove useless doc comments
alcaeus 11621f5
Make lazy BSON classes final
alcaeus 3426ce1
Implement Countable in lazy BSON structures
alcaeus b08bd8e
Make lazy BSON classes serializable
alcaeus 6708343
Implement JsonSerializable in lazy BSON classes
alcaeus 74f48ae
Rename AsListIterator to ListIterator
alcaeus 98c0313
Remove null-coalesce assignment
alcaeus b1bf347
Rename readFrom* methods for consistency
alcaeus 8cb8d7c
Defer index update in ListIterator until after parent operation
alcaeus 466473a
Use data provider for tests
alcaeus 476080f
Improve assertions in lazy codec tests
alcaeus 61c586d
Remove duplicate assertions
alcaeus 21d5342
Clarify comment in tests
alcaeus 2aad7f3
Rename KnowsCodecLibrary interface to CodecLibraryAware
alcaeus c3ab097
Allow lists with gap when building LazyBSONArrays
alcaeus 8599960
Add clarifying comment when marking fields as existing
alcaeus 82775ec
Use object in codec test
alcaeus 9aa174d
Add comment explaining manual creation of nested lazy structures
alcaeus 9f9254b
Ensure keys are sorted correctly in LazyBSONArray
alcaeus cf9af04
Address code review feedback
alcaeus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
<?php | ||
/* | ||
* Copyright 2023-present MongoDB, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace MongoDB\Codec; | ||
|
||
use MongoDB\Exception\UnsupportedValueException; | ||
|
||
use function array_map; | ||
use function is_array; | ||
|
||
/** | ||
* Codec to recursively encode/decode values in arrays. | ||
* | ||
* @template-implements Codec<array, array> | ||
*/ | ||
final class ArrayCodec implements Codec, CodecLibraryAware | ||
{ | ||
private ?CodecLibrary $library = null; | ||
|
||
public function attachCodecLibrary(CodecLibrary $library): void | ||
{ | ||
$this->library = $library; | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @psalm-assert-if-true array $value | ||
*/ | ||
public function canDecode($value): bool | ||
{ | ||
return is_array($value); | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @psalm-assert-if-true array $value | ||
*/ | ||
public function canEncode($value): bool | ||
{ | ||
return is_array($value); | ||
} | ||
|
||
/** @param mixed $value */ | ||
public function decode($value): array | ||
{ | ||
if (! $this->canDecode($value)) { | ||
throw UnsupportedValueException::invalidDecodableValue($value); | ||
} | ||
|
||
return array_map( | ||
[$this->getLibrary(), 'decodeIfSupported'], | ||
$value, | ||
); | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @return mixed | ||
* @psalm-return ($value is array ? array : $value) | ||
*/ | ||
public function decodeIfSupported($value) | ||
{ | ||
return $this->canDecode($value) ? $this->decode($value) : $value; | ||
} | ||
|
||
/** @param mixed $value */ | ||
public function encode($value): array | ||
{ | ||
if (! $this->canEncode($value)) { | ||
throw UnsupportedValueException::invalidEncodableValue($value); | ||
} | ||
|
||
return array_map( | ||
[$this->getLibrary(), 'encodeIfSupported'], | ||
$value, | ||
); | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @return mixed | ||
* @psalm-return ($value is array ? array : $value) | ||
*/ | ||
public function encodeIfSupported($value) | ||
{ | ||
return $this->canEncode($value) ? $this->encode($value) : $value; | ||
} | ||
|
||
private function getLibrary(): CodecLibrary | ||
{ | ||
if (! $this->library) { | ||
$this->library = new CodecLibrary(); | ||
} | ||
|
||
return $this->library; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<?php | ||
/* | ||
* Copyright 2023-present MongoDB, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace MongoDB\Codec; | ||
|
||
use MongoDB\BSON\PackedArray; | ||
use MongoDB\Exception\UnsupportedValueException; | ||
use MongoDB\Model\LazyBSONArray; | ||
|
||
/** | ||
* Codec for lazy decoding of BSON PackedArray instances | ||
* | ||
* @template-implements Codec<PackedArray, LazyBSONArray> | ||
*/ | ||
final class LazyBSONArrayCodec implements Codec, CodecLibraryAware | ||
{ | ||
private ?CodecLibrary $library = null; | ||
|
||
public function attachCodecLibrary(CodecLibrary $library): void | ||
{ | ||
$this->library = $library; | ||
alcaeus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @psalm-assert-if-true PackedArray $value | ||
*/ | ||
public function canDecode($value): bool | ||
{ | ||
return $value instanceof PackedArray; | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @psalm-assert-if-true LazyBSONArray $value | ||
*/ | ||
public function canEncode($value): bool | ||
{ | ||
return $value instanceof LazyBSONArray; | ||
} | ||
|
||
/** @param mixed $value */ | ||
public function decode($value): LazyBSONArray | ||
{ | ||
if (! $value instanceof PackedArray) { | ||
throw UnsupportedValueException::invalidDecodableValue($value); | ||
} | ||
|
||
return new LazyBSONArray($value, $this->getLibrary()); | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @return mixed | ||
* @psalm-return ($value is PackedArray ? LazyBSONArray : $value) | ||
*/ | ||
public function decodeIfSupported($value) | ||
{ | ||
return $this->canDecode($value) ? $this->decode($value) : $value; | ||
} | ||
|
||
/** @param mixed $value */ | ||
public function encode($value): PackedArray | ||
{ | ||
if (! $value instanceof LazyBSONArray) { | ||
throw UnsupportedValueException::invalidEncodableValue($value); | ||
} | ||
|
||
$return = []; | ||
/** @var mixed $offsetValue */ | ||
foreach ($value as $offsetValue) { | ||
$return[] = $this->getLibrary()->encodeIfSupported($offsetValue); | ||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return PackedArray::fromPHP($return); | ||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
* @param mixed $value | ||
* @return mixed | ||
* @psalm-return ($value is LazyBSONArray ? PackedArray : $value) | ||
*/ | ||
public function encodeIfSupported($value) | ||
{ | ||
return $this->canEncode($value) ? $this->encode($value) : $value; | ||
} | ||
|
||
private function getLibrary(): CodecLibrary | ||
{ | ||
if (! $this->library) { | ||
$this->library = new LazyBSONCodecLibrary(); | ||
} | ||
|
||
return $this->library; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
/* | ||
* Copyright 2023-present MongoDB, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
namespace MongoDB\Codec; | ||
|
||
final class LazyBSONCodecLibrary extends CodecLibrary | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct( | ||
new LazyBSONDocumentCodec(), | ||
new LazyBSONArrayCodec(), | ||
new ArrayCodec(), | ||
new ObjectCodec(), | ||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.