Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
489d8698
Commit
489d8698
authored
Apr 10, 2018
by
Katherine Walker
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PHPLIB-262: Implement iterator for BSON files
parent
df6df1c5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
268 additions
and
0 deletions
+268
-0
BSONIterator.php
src/Model/BSONIterator.php
+135
-0
BSONIteratorTest.php
tests/Model/BSONIteratorTest.php
+133
-0
No files found.
src/Model/BSONIterator.php
0 → 100644
View file @
489d8698
<?php
/*
* Copyright 2018 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
*
* http://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\Model
;
use
MongoDB\Exception\UnexpectedValueException
;
use
MongoDB\Model\BSONDocument
;
use
Iterator
;
/**
* Iterator for BSON documents.
*/
class
BSONIterator
implements
Iterator
{
private
$buffer
;
private
$bufferLength
;
private
$current
;
private
$key
=
0
;
private
$position
=
0
;
private
$options
;
const
BSON_SIZE
=
4
;
/**
* Constructs a BSON Iterator.
*
* Supported options:
*
* * typeMap (array): Type map for BSON deserialization.
*
* @internal
* @see http://php.net/manual/en/function.mongodb.bson-tophp.php
* @param string $data Concatenated, valid, BSON-encoded documents
* @param array $options Iterator options
* @throws InvalidArgumentException for parameter/option parsing errors
*/
public
function
__construct
(
$data
,
array
$options
=
[])
{
if
(
isset
(
$options
[
'typeMap'
])
&&
!
is_array
(
$options
[
'typeMap'
]))
{
throw
InvalidArgumentException
::
invalidType
(
'"typeMap" option'
,
$options
[
'typeMap'
],
'array'
);
}
if
(
!
isset
(
$options
[
'typeMap'
]))
{
$options
[
'typeMap'
]
=
[];
}
$this
->
buffer
=
$data
;
$this
->
bufferLength
=
strlen
(
$data
);
$this
->
options
=
$options
;
}
/**
* @see http://php.net/iterator.current
* @return mixed
*/
public
function
current
()
{
return
$this
->
current
;
}
/**
* @see http://php.net/iterator.key
* @return mixed
*/
public
function
key
()
{
return
$this
->
key
;
}
/**
* @see http://php.net/iterator.next
* @return void
*/
public
function
next
()
{
$this
->
key
++
;
$this
->
current
=
null
;
$this
->
advance
();
}
/**
* @see http://php.net/iterator.rewind
* @return void
*/
public
function
rewind
()
{
$this
->
key
=
0
;
$this
->
position
=
0
;
$this
->
current
=
null
;
$this
->
advance
();
}
/**
* @see http://php.net/iterator.valid
* @return boolean
*/
public
function
valid
()
{
return
$this
->
current
!==
null
;
}
private
function
advance
()
{
if
(
$this
->
position
===
$this
->
bufferLength
)
{
return
;
}
if
((
$this
->
bufferLength
-
$this
->
position
)
<
self
::
BSON_SIZE
)
{
throw
new
UnexpectedValueException
(
sprintf
(
'Expected at least %d bytes; %d remaining'
,
self
::
BSON_SIZE
,
$this
->
bufferLength
-
$this
->
position
));
}
list
(,
$documentLength
)
=
unpack
(
'V'
,
substr
(
$this
->
buffer
,
$this
->
position
,
self
::
BSON_SIZE
));
if
((
$this
->
bufferLength
-
$this
->
position
)
<
$documentLength
)
{
throw
new
UnexpectedValueException
(
sprintf
(
'Expected %d bytes; %d remaining'
,
$documentLength
,
$this
->
bufferLength
-
$this
->
position
));
}
$this
->
current
=
\MongoDB\BSON\toPHP
(
substr
(
$this
->
buffer
,
$this
->
position
,
$documentLength
),
$this
->
options
[
'typeMap'
]);
$this
->
position
+=
$documentLength
;
}
}
tests/Model/BSONIteratorTest.php
0 → 100644
View file @
489d8698
<?php
namespace
MongoDB\Tests\Model
;
use
MongoDB\Exception\UnexpectedValueException
;
use
MongoDB\Model\BSONArray
;
use
MongoDB\Model\BSONDocument
;
use
MongoDB\Model\BSONIterator
;
use
MongoDB\Tests\TestCase
;
use
stdClass
;
class
BSONIteratorTest
extends
TestCase
{
/**
* @dataProvider provideTypeMapOptionsAndExpectedDocuments
*/
public
function
testValidValues
(
array
$typeMap
=
null
,
$binaryString
,
array
$expectedDocuments
)
{
$bsonIt
=
new
BSONIterator
(
$binaryString
,
[
'typeMap'
=>
$typeMap
]);
$results
=
iterator_to_array
(
$bsonIt
);
$this
->
assertEquals
(
$expectedDocuments
,
$results
);
}
public
function
provideTypeMapOptionsAndExpectedDocuments
()
{
return
[
[
null
,
implode
(
array_map
(
'MongoDB\BSON\fromPHP'
,
[
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
)),
[
(
object
)
[
'_id'
=>
1
,
'x'
=>
(
object
)
[
'foo'
=>
'bar'
]],
(
object
)
[
'_id'
=>
3
,
'x'
=>
(
object
)
[
'foo'
=>
'bar'
]],
]
],
[
[
'root'
=>
'array'
,
'document'
=>
'array'
],
implode
(
array_map
(
'MongoDB\BSON\fromPHP'
,
[
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
)),
[
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
],
[
[
'root'
=>
'object'
,
'document'
=>
'array'
],
implode
(
array_map
(
'MongoDB\BSON\fromPHP'
,
[
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
)),
[
(
object
)
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
(
object
)
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
],
[
[
'root'
=>
'array'
,
'document'
=>
'stdClass'
],
implode
(
array_map
(
'MongoDB\BSON\fromPHP'
,
[
[
'_id'
=>
1
,
'x'
=>
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
[
'foo'
=>
'bar'
]],
]
)),
[
[
'_id'
=>
1
,
'x'
=>
(
object
)
[
'foo'
=>
'bar'
]],
[
'_id'
=>
3
,
'x'
=>
(
object
)
[
'foo'
=>
'bar'
]],
]
],
];
}
public
function
testCannotReadLengthFromFirstDocument
()
{
$binaryString
=
substr
(
\MongoDB\BSON\fromPHP
([]),
0
,
3
);
$bsonIt
=
new
BSONIterator
(
$binaryString
);
$this
->
expectException
(
UnexpectedValueException
::
class
);
$this
->
expectExceptionMessage
(
'Expected at least 4 bytes; 3 remaining'
);
$bsonIt
->
rewind
();
}
public
function
testCannotReadLengthFromSubsequentDocument
()
{
$binaryString
=
\MongoDB\BSON\fromPHP
([])
.
substr
(
\MongoDB\BSON\fromPHP
([]),
0
,
3
);
$bsonIt
=
new
BSONIterator
(
$binaryString
);
$bsonIt
->
rewind
();
$this
->
expectException
(
UnexpectedValueException
::
class
);
$this
->
expectExceptionMessage
(
'Expected at least 4 bytes; 3 remaining'
);
$bsonIt
->
next
();
}
public
function
testCannotReadFirstDocument
()
{
$binaryString
=
substr
(
\MongoDB\BSON\fromPHP
([]),
0
,
4
);
$bsonIt
=
new
BSONIterator
(
$binaryString
);
$this
->
expectException
(
UnexpectedValueException
::
class
);
$this
->
expectExceptionMessage
(
'Expected 5 bytes; 4 remaining'
);
$bsonIt
->
rewind
();
}
public
function
testCannotReadSecondDocument
()
{
$binaryString
=
\MongoDB\BSON\fromPHP
([])
.
substr
(
\MongoDB\BSON\fromPHP
([]),
0
,
4
);
$bsonIt
=
new
BSONIterator
(
$binaryString
);
$bsonIt
->
rewind
();
$this
->
expectException
(
UnexpectedValueException
::
class
);
$this
->
expectExceptionMessage
(
'Expected 5 bytes; 4 remaining'
);
$bsonIt
->
next
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment