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
02e651cb
Commit
02e651cb
authored
Jun 15, 2015
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extract Collection findAndModify methods to operation classes
parent
e36a304c
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
556 additions
and
262 deletions
+556
-262
Collection.php
src/Collection.php
+40
-254
FindAndModify.php
src/Operation/FindAndModify.php
+179
-0
FindOneAndDelete.php
src/Operation/FindOneAndDelete.php
+83
-0
FindOneAndReplace.php
src/Operation/FindOneAndReplace.php
+122
-0
FindOneAndUpdate.php
src/Operation/FindOneAndUpdate.php
+122
-0
FindOneAndReplaceFunctionalTest.php
...s/Collection/CrudSpec/FindOneAndReplaceFunctionalTest.php
+5
-4
FindOneAndUpdateFunctionalTest.php
tests/Collection/CrudSpec/FindOneAndUpdateFunctionalTest.php
+5
-4
No files found.
src/Collection.php
View file @
02e651cb
...
...
@@ -19,6 +19,9 @@ use MongoDB\Operation\Aggregate;
use
MongoDB\Operation\CreateIndexes
;
use
MongoDB\Operation\Count
;
use
MongoDB\Operation\Distinct
;
use
MongoDB\Operation\FindOneAndDelete
;
use
MongoDB\Operation\FindOneAndReplace
;
use
MongoDB\Operation\FindOneAndUpdate
;
use
Traversable
;
class
Collection
...
...
@@ -452,103 +455,63 @@ class Collection
/**
* Finds a single document and deletes it, returning the original.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @see Collection::getFindOneAndDelete() for supported $options
* The document to return may be null.
*
* @param array $filter The $filter criteria to search for
* @param array $options Additional options
* @return array The original document
* @see FindOneAndDelete::__construct() for supported options
* @param array|object $filter Query by which to filter documents
* @param array $options Command options
* @return array|null
*/
public
function
findOneAndDelete
(
array
$filter
,
array
$options
=
array
())
public
function
findOneAndDelete
(
$filter
,
array
$options
=
array
())
{
$options
=
array_merge
(
$this
->
getFindOneAndDeleteOptions
(),
$options
);
$options
=
$this
->
_massageFindAndModifyOptions
(
$options
);
$cmd
=
array
(
"findandmodify"
=>
$this
->
collname
,
"query"
=>
$filter
,
)
+
$options
;
$doc
=
current
(
$this
->
_runCommand
(
$this
->
dbname
,
$cmd
)
->
toArray
());
if
(
$doc
[
"ok"
])
{
return
is_object
(
$doc
[
"value"
])
?
(
array
)
$doc
[
"value"
]
:
$doc
[
"value"
];
}
$operation
=
new
FindOneAndDelete
(
$this
->
dbname
,
$this
->
collname
,
$filter
,
$options
);
$server
=
$this
->
manager
->
selectServer
(
new
ReadPreference
(
ReadPreference
::
RP_PRIMARY
));
throw
$this
->
_generateCommandException
(
$doc
);
return
$operation
->
execute
(
$server
);
}
/**
* Finds a single document and replaces it, returning either the original or the replaced document
* By default, returns the original document.
* To return the new document set:
* $options = array("returnDocument" => Collection::FIND_ONE_AND_RETURN_AFTER);
* Finds a single document and replaces it, returning either the original or
* the replaced document.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @see Collection::getFindOneAndReplace() for supported $options
* The document to return may be null. By default, the original document is
* returned. Specify FindOneAndReplace::RETURN_DOCUMENT_AFTER for the
* "returnDocument" option to return the updated document.
*
* @param array $filter The $filter criteria to search for
* @param array $replacement The document to replace with
* @param array $options Additional options
* @return array
* @see FindOneAndReplace::__construct() for supported options
* @param array|object $filter Query by which to filter documents
* @param array|object $replacement Replacement document
* @param array $options Command options
* @return array|null
*/
public
function
findOneAndReplace
(
array
$filter
,
array
$replacement
,
array
$options
=
array
())
public
function
findOneAndReplace
(
$filter
,
$replacement
,
array
$options
=
array
())
{
$firstKey
=
key
(
$replacement
);
if
(
isset
(
$firstKey
[
0
])
&&
$firstKey
[
0
]
==
'$'
)
{
throw
new
InvalidArgumentException
(
"First key in
\$
replacement must NOT be a
\$
operator"
);
}
$options
=
array_merge
(
$this
->
getFindOneAndReplaceOptions
(),
$options
);
$options
=
$this
->
_massageFindAndModifyOptions
(
$options
,
$replacement
);
$cmd
=
array
(
"findandmodify"
=>
$this
->
collname
,
"query"
=>
$filter
,
)
+
$options
;
$doc
=
current
(
$this
->
_runCommand
(
$this
->
dbname
,
$cmd
)
->
toArray
());
if
(
$doc
[
"ok"
])
{
return
$this
->
_massageFindAndModifyResult
(
$doc
,
$options
);
}
$operation
=
new
FindOneAndReplace
(
$this
->
dbname
,
$this
->
collname
,
$filter
,
$replacement
,
$options
);
$server
=
$this
->
manager
->
selectServer
(
new
ReadPreference
(
ReadPreference
::
RP_PRIMARY
));
throw
$this
->
_generateCommandException
(
$doc
);
return
$operation
->
execute
(
$server
);
}
/**
* Finds a single document and updates it, returning either the original or the updated document
* By default, returns the original document.
* To return the new document set:
* $options = array("returnDocument" => Collection::FIND_ONE_AND_RETURN_AFTER);
* Finds a single document and updates it, returning either the original or
* the updated document.
*
* The document to return may be null. By default, the original document is
* returned. Specify FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the
* "returnDocument" option to return the updated document.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
* @see Collection::getFindOneAndUpdate() for supported $options
*
* @param array $filter The $filter criteria to search for
* @param array $update An array of update operators to apply to the document
* @param array $options Additional options
* @return array
* @see FindOneAndReplace::__construct() for supported options
* @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document
* @param array $options Command options
* @return array|null
*/
public
function
findOneAndUpdate
(
array
$filter
,
array
$update
,
array
$options
=
array
())
public
function
findOneAndUpdate
(
$filter
,
$update
,
array
$options
=
array
())
{
$firstKey
=
key
(
$update
);
if
(
!
isset
(
$firstKey
[
0
])
||
$firstKey
[
0
]
!=
'$'
)
{
throw
new
InvalidArgumentException
(
"First key in
\$
update must be a
\$
operator"
);
}
$options
=
array_merge
(
$this
->
getFindOneAndUpdateOptions
(),
$options
);
$options
=
$this
->
_massageFindAndModifyOptions
(
$options
,
$update
);
$cmd
=
array
(
"findandmodify"
=>
$this
->
collname
,
"query"
=>
$filter
,
)
+
$options
;
$doc
=
current
(
$this
->
_runCommand
(
$this
->
dbname
,
$cmd
)
->
toArray
());
if
(
$doc
[
"ok"
])
{
return
$this
->
_massageFindAndModifyResult
(
$doc
,
$options
);
}
$operation
=
new
FindOneAndUpdate
(
$this
->
dbname
,
$this
->
collname
,
$filter
,
$update
,
$options
);
$server
=
$this
->
manager
->
selectServer
(
new
ReadPreference
(
ReadPreference
::
RP_PRIMARY
));
throw
$this
->
_generateCommandException
(
$doc
);
return
$operation
->
execute
(
$server
);
}
/**
...
...
@@ -583,133 +546,6 @@ class Collection
return
$this
->
dbname
;
}
/**
* Retrieves all findOneDelete options with their default values.
*
* @return array of Collection::findOneAndDelete() options
*/
public
function
getFindOneAndDeleteOptions
()
{
return
array
(
/**
* The maximum amount of time to allow the query to run.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"maxTimeMS"
=>
0
,
/**
* Limits the fields to return for all matching documents.
*
* @see http://docs.mongodb.org/manual/tutorial/project-fields-from-query-results
*/
"projection"
=>
array
(),
/**
* Determines which document the operation modifies if the query selects multiple documents.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"sort"
=>
array
(),
);
}
/**
* Retrieves all findOneAndReplace options with their default values.
*
* @return array of Collection::findOneAndReplace() options
*/
public
function
getFindOneAndReplaceOptions
()
{
return
array
(
/**
* The maximum amount of time to allow the query to run.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"maxTimeMS"
=>
0
,
/**
* Limits the fields to return for all matching documents.
*
* @see http://docs.mongodb.org/manual/tutorial/project-fields-from-query-results
*/
"projection"
=>
array
(),
/**
* When ReturnDocument.After, returns the replaced or inserted document rather than the original.
* Defaults to ReturnDocument.Before.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"returnDocument"
=>
self
::
FIND_ONE_AND_RETURN_BEFORE
,
/**
* Determines which document the operation modifies if the query selects multiple documents.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"sort"
=>
array
(),
/**
* When true, findAndModify creates a new document if no document matches the query. The
* default is false.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"upsert"
=>
false
,
);
}
/**
* Retrieves all findOneAndUpdate options with their default values.
*
* @return array of Collection::findOneAndUpdate() options
*/
public
function
getFindOneAndUpdateOptions
()
{
return
array
(
/**
* The maximum amount of time to allow the query to run.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"maxTimeMS"
=>
0
,
/**
* Limits the fields to return for all matching documents.
*
* @see http://docs.mongodb.org/manual/tutorial/project-fields-from-query-results
*/
"projection"
=>
array
(),
/**
* When ReturnDocument.After, returns the updated or inserted document rather than the original.
* Defaults to ReturnDocument.Before.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"returnDocument"
=>
self
::
FIND_ONE_AND_RETURN_BEFORE
,
/**
* Determines which document the operation modifies if the query selects multiple documents.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"sort"
=>
array
(),
/**
* When true, creates a new document if no document matches the query. The default is false.
*
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
"upsert"
=>
false
,
);
}
/**
* Retrieves all find options with their default values.
*
...
...
@@ -1025,56 +861,6 @@ class Collection
return
new
RuntimeException
(
"FIXME: Unknown error"
);
}
/**
* Internal helper for massaging findandmodify options
* @internal
*/
final
protected
function
_massageFindAndModifyOptions
(
$options
,
$update
=
array
())
{
$ret
=
array
(
"sort"
=>
$options
[
"sort"
],
"new"
=>
isset
(
$options
[
"returnDocument"
])
?
$options
[
"returnDocument"
]
==
self
::
FIND_ONE_AND_RETURN_AFTER
:
false
,
"fields"
=>
$options
[
"projection"
],
"upsert"
=>
isset
(
$options
[
"upsert"
])
?
$options
[
"upsert"
]
:
false
,
);
if
(
$update
)
{
$ret
[
"update"
]
=
$update
;
}
else
{
$ret
[
"remove"
]
=
true
;
}
return
$ret
;
}
/**
* Internal helper for massaging the findAndModify result.
*
* @internal
* @param array $result
* @param array $options
* @return array|null
*/
final
protected
function
_massageFindAndModifyResult
(
array
$result
,
array
$options
)
{
if
(
$result
[
'value'
]
===
null
)
{
return
null
;
}
/* Prior to 3.0, findAndModify returns an empty document instead of null
* when an upsert is performed and the pre-modified document was
* requested.
*/
if
(
$options
[
'upsert'
]
&&
!
$options
[
'new'
]
&&
isset
(
$result
[
'lastErrorObject'
]
->
updatedExisting
)
&&
!
$result
[
'lastErrorObject'
]
->
updatedExisting
)
{
return
null
;
}
return
is_object
(
$result
[
"value"
])
?
(
array
)
$result
[
'value'
]
:
$result
[
'value'
];
}
/**
* Constructs the Query Wire Protocol field 'flags' based on $options
* provided to other helpers
...
...
src/Operation/FindAndModify.php
0 → 100644
View file @
02e651cb
<?php
namespace
MongoDB\Operation
;
use
MongoDB\Driver\Command
;
use
MongoDB\Driver\Server
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
use
MongoDB\Exception\RuntimeException
;
use
MongoDB\Exception\UnexpectedValueException
;
/**
* Operation for the findAndModify command.
*
* This class is used internally by the FindOneAndDelete, FindOneAndReplace, and
* FindOneAndUpdate operation classes.
*
* @internal
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
class
FindAndModify
implements
Executable
{
private
$databaseName
;
private
$collectionName
;
private
$options
;
/**
* Constructs a findAndModify command.
*
* Supported options:
*
* * fields (document): Limits the fields to return for the matching
* document.
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
* * new (boolean): When true, returns the modified document rather than
* the original. This option is ignored for remove operations. The
* The default is false.
*
* * query (document): Query by which to filter documents.
*
* * remove (boolean): When true, removes the matched document. This option
* cannot be true if the update option is set. The default is false.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
*
* * update (document): Update or replacement to apply to the matched
* document. This option cannot be set if the remove option is true.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. This option is ignored for remove operations. The
* default is false.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array $options Command options
* @throws InvalidArgumentException
*/
public
function
__construct
(
$databaseName
,
$collectionName
,
array
$options
)
{
$options
+=
array
(
'new'
=>
false
,
'remove'
=>
false
,
'upsert'
=>
false
,
);
if
(
isset
(
$options
[
'fields'
])
&&
!
is_array
(
$options
[
'fields'
])
&&
!
is_object
(
$options
[
'fields'
]))
{
throw
new
InvalidArgumentTypeException
(
'"fields" option'
,
$options
[
'fields'
],
'array or object'
);
}
if
(
isset
(
$options
[
'maxTimeMS'
])
&&
!
is_integer
(
$options
[
'maxTimeMS'
]))
{
throw
new
InvalidArgumentTypeException
(
'"maxTimeMS" option'
,
$options
[
'maxTimeMS'
],
'integer'
);
}
if
(
!
is_bool
(
$options
[
'new'
]))
{
throw
new
InvalidArgumentTypeException
(
'"new" option'
,
$options
[
'new'
],
'boolean'
);
}
if
(
isset
(
$options
[
'query'
])
&&
!
is_array
(
$options
[
'query'
])
&&
!
is_object
(
$options
[
'query'
]))
{
throw
new
InvalidArgumentTypeException
(
'"query" option'
,
$options
[
'query'
],
'array or object'
);
}
if
(
!
is_bool
(
$options
[
'remove'
]))
{
throw
new
InvalidArgumentTypeException
(
'"remove" option'
,
$options
[
'remove'
],
'boolean'
);
}
if
(
isset
(
$options
[
'sort'
])
&&
!
is_array
(
$options
[
'sort'
])
&&
!
is_object
(
$options
[
'sort'
]))
{
throw
new
InvalidArgumentTypeException
(
'"sort" option'
,
$options
[
'sort'
],
'array or object'
);
}
if
(
isset
(
$options
[
'update'
])
&&
!
is_array
(
$options
[
'update'
])
&&
!
is_object
(
$options
[
'update'
]))
{
throw
new
InvalidArgumentTypeException
(
'"update" option'
,
$options
[
'update'
],
'array or object'
);
}
if
(
!
is_bool
(
$options
[
'upsert'
]))
{
throw
new
InvalidArgumentTypeException
(
'"upsert" option'
,
$options
[
'upsert'
],
'boolean'
);
}
if
(
!
(
isset
(
$options
[
'update'
])
xor
$options
[
'remove'
]))
{
throw
new
InvalidArgumentException
(
'The "remove" option must be true or an "update" document must be specified, but not both'
);
}
$this
->
databaseName
=
(
string
)
$databaseName
;
$this
->
collectionName
=
(
string
)
$collectionName
;
$this
->
options
=
$options
;
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return array|null
*/
public
function
execute
(
Server
$server
)
{
$cursor
=
$server
->
executeCommand
(
$this
->
databaseName
,
$this
->
createCommand
());
$result
=
current
(
$cursor
->
toArray
());
if
(
empty
(
$result
[
'ok'
]))
{
throw
new
RuntimeException
(
isset
(
$result
[
'errmsg'
])
?
$result
[
'errmsg'
]
:
'Unknown error'
);
}
if
(
!
isset
(
$result
[
'value'
]))
{
return
null
;
}
/* Prior to 3.0, findAndModify returns an empty document instead of null
* when an upsert is performed and the pre-modified document was
* requested.
*/
if
(
$this
->
options
[
'upsert'
]
&&
!
$this
->
options
[
'new'
]
&&
isset
(
$result
[
'lastErrorObject'
]
->
updatedExisting
)
&&
!
$result
[
'lastErrorObject'
]
->
updatedExisting
)
{
return
null
;
}
if
(
!
is_object
(
$result
[
'value'
]))
{
throw
new
UnexpectedValueException
(
'findAndModify command did not return a "value" document'
);
}
return
(
array
)
$result
[
'value'
];
}
/**
* Create the findAndModify command.
*
* @return Command
*/
private
function
createCommand
()
{
$cmd
=
array
(
'findAndModify'
=>
$this
->
collectionName
,
);
if
(
$this
->
options
[
'remove'
])
{
$cmd
[
'remove'
]
=
true
;
}
else
{
$cmd
[
'new'
]
=
$this
->
options
[
'new'
];
$cmd
[
'upsert'
]
=
$this
->
options
[
'upsert'
];
}
foreach
(
array
(
'fields'
,
'query'
,
'sort'
,
'update'
)
as
$option
)
{
if
(
isset
(
$this
->
options
[
$option
]))
{
$cmd
[
$option
]
=
(
object
)
$this
->
options
[
$option
];
}
}
if
(
isset
(
$this
->
options
[
'maxTimeMS'
]))
{
$cmd
[
'maxTimeMS'
]
=
$this
->
options
[
'maxTimeMS'
];
}
return
new
Command
(
$cmd
);
}
}
src/Operation/FindOneAndDelete.php
0 → 100644
View file @
02e651cb
<?php
namespace
MongoDB\Operation
;
use
MongoDB\Driver\Command
;
use
MongoDB\Driver\Server
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
/**
* Operation for deleting a document with the findAndModify command.
*
* @api
* @see MongoDB\Collection::findOneAndDelete()
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
class
FindOneAndDelete
implements
Executable
{
private
$findAndModify
;
/**
* Constructs a findAndModify command for deleting a document.
*
* Supported options:
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
* * projection (document): Limits the fields to return for the matching
* document.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array $options Command options
* @throws InvalidArgumentException
*/
public
function
__construct
(
$databaseName
,
$collectionName
,
$filter
,
array
$options
=
array
())
{
if
(
!
is_array
(
$filter
)
&&
!
is_object
(
$filter
))
{
throw
new
InvalidArgumentTypeException
(
'$filter'
,
$filter
,
'array or object'
);
}
if
(
isset
(
$options
[
'maxTimeMS'
])
&&
!
is_integer
(
$options
[
'maxTimeMS'
]))
{
throw
new
InvalidArgumentTypeException
(
'"maxTimeMS" option'
,
$options
[
'maxTimeMS'
],
'integer'
);
}
if
(
isset
(
$options
[
'projection'
])
&&
!
is_array
(
$options
[
'projection'
])
&&
!
is_object
(
$options
[
'projection'
]))
{
throw
new
InvalidArgumentTypeException
(
'"projection" option'
,
$options
[
'projection'
],
'array or object'
);
}
if
(
isset
(
$options
[
'sort'
])
&&
!
is_array
(
$options
[
'sort'
])
&&
!
is_object
(
$options
[
'sort'
]))
{
throw
new
InvalidArgumentTypeException
(
'"sort" option'
,
$options
[
'sort'
],
'array or object'
);
}
$this
->
findAndModify
=
new
FindAndModify
(
$databaseName
,
$collectionName
,
array
(
'fields'
=>
isset
(
$options
[
'projection'
])
?
$options
[
'projection'
]
:
null
,
'maxTimeMS'
=>
isset
(
$options
[
'maxTimeMS'
])
?
$options
[
'maxTimeMS'
]
:
null
,
'query'
=>
$filter
,
'remove'
=>
true
,
'sort'
=>
isset
(
$options
[
'sort'
])
?
$options
[
'sort'
]
:
null
,
)
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return array|null
*/
public
function
execute
(
Server
$server
)
{
return
$this
->
findAndModify
->
execute
(
$server
);
}
}
src/Operation/FindOneAndReplace.php
0 → 100644
View file @
02e651cb
<?php
namespace
MongoDB\Operation
;
use
MongoDB\Driver\Command
;
use
MongoDB\Driver\Server
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
/**
* Operation for replacing a document with the findAndModify command.
*
* @api
* @see MongoDB\Collection::findOneAndReplace()
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
class
FindOneAndReplace
implements
Executable
{
const
RETURN_DOCUMENT_BEFORE
=
1
;
const
RETURN_DOCUMENT_AFTER
=
2
;
private
$findAndModify
;
/**
* Constructs a findAndModify command for replacing a document.
*
* Supported options:
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
* * projection (document): Limits the fields to return for the matching
* document.
*
* * returnDocument (enum): Whether to return the document before or after
* the update is applied. Must be either RETURN_DOCUMENT_BEFORE or
* RETURN_DOCUMENT_AFTER. The default is RETURN_DOCUMENT_BEFORE.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array|object $replacement Replacement document
* @param array $options Command options
* @throws InvalidArgumentException
*/
public
function
__construct
(
$databaseName
,
$collectionName
,
$filter
,
$replacement
,
array
$options
=
array
())
{
if
(
!
is_array
(
$filter
)
&&
!
is_object
(
$filter
))
{
throw
new
InvalidArgumentTypeException
(
'$filter'
,
$filter
,
'array or object'
);
}
if
(
!
is_array
(
$replacement
)
&&
!
is_object
(
$replacement
))
{
throw
new
InvalidArgumentTypeException
(
'$replacement'
,
$replacement
,
'array or object'
);
}
if
(
\MongoDB\is_first_key_operator
(
$replacement
))
{
throw
new
InvalidArgumentException
(
'First key in $replacement argument is an update operator'
);
}
$options
+=
array
(
'returnDocument'
=>
self
::
RETURN_DOCUMENT_BEFORE
,
'upsert'
=>
false
,
);
if
(
isset
(
$options
[
'maxTimeMS'
])
&&
!
is_integer
(
$options
[
'maxTimeMS'
]))
{
throw
new
InvalidArgumentTypeException
(
'"maxTimeMS" option'
,
$options
[
'maxTimeMS'
],
'integer'
);
}
if
(
isset
(
$options
[
'projection'
])
&&
!
is_array
(
$options
[
'projection'
])
&&
!
is_object
(
$options
[
'projection'
]))
{
throw
new
InvalidArgumentTypeException
(
'"projection" option'
,
$options
[
'projection'
],
'array or object'
);
}
if
(
!
is_integer
(
$options
[
'returnDocument'
]))
{
throw
new
InvalidArgumentTypeException
(
'"returnDocument" option'
,
$options
[
'returnDocument'
],
'integer'
);
}
if
(
$options
[
'returnDocument'
]
!==
self
::
RETURN_DOCUMENT_AFTER
&&
$options
[
'returnDocument'
]
!==
self
::
RETURN_DOCUMENT_BEFORE
)
{
throw
new
InvalidArgumentException
(
'Invalid value for "returnDocument" option: '
.
$options
[
'returnDocument'
]);
}
if
(
isset
(
$options
[
'sort'
])
&&
!
is_array
(
$options
[
'sort'
])
&&
!
is_object
(
$options
[
'sort'
]))
{
throw
new
InvalidArgumentTypeException
(
'"sort" option'
,
$options
[
'sort'
],
'array or object'
);
}
if
(
!
is_bool
(
$options
[
'upsert'
]))
{
throw
new
InvalidArgumentTypeException
(
'"upsert" option'
,
$options
[
'upsert'
],
'boolean'
);
}
$this
->
findAndModify
=
new
FindAndModify
(
$databaseName
,
$collectionName
,
array
(
'fields'
=>
isset
(
$options
[
'projection'
])
?
$options
[
'projection'
]
:
null
,
'maxTimeMS'
=>
isset
(
$options
[
'maxTimeMS'
])
?
$options
[
'maxTimeMS'
]
:
null
,
'new'
=>
$options
[
'returnDocument'
]
===
self
::
RETURN_DOCUMENT_AFTER
,
'query'
=>
$filter
,
'sort'
=>
isset
(
$options
[
'sort'
])
?
$options
[
'sort'
]
:
null
,
'update'
=>
$replacement
,
'upsert'
=>
$options
[
'upsert'
],
)
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return array|null
*/
public
function
execute
(
Server
$server
)
{
return
$this
->
findAndModify
->
execute
(
$server
);
}
}
src/Operation/FindOneAndUpdate.php
0 → 100644
View file @
02e651cb
<?php
namespace
MongoDB\Operation
;
use
MongoDB\Driver\Command
;
use
MongoDB\Driver\Server
;
use
MongoDB\Exception\InvalidArgumentException
;
use
MongoDB\Exception\InvalidArgumentTypeException
;
/**
* Operation for updating a document with the findAndModify command.
*
* @api
* @see MongoDB\Collection::findOneAndUpdate()
* @see http://docs.mongodb.org/manual/reference/command/findAndModify/
*/
class
FindOneAndUpdate
implements
Executable
{
const
RETURN_DOCUMENT_BEFORE
=
1
;
const
RETURN_DOCUMENT_AFTER
=
2
;
private
$findAndModify
;
/**
* Constructs a findAndModify command for updating a document.
*
* Supported options:
*
* * maxTimeMS (integer): The maximum amount of time to allow the query to
* run.
*
* * projection (document): Limits the fields to return for the matching
* document.
*
* * returnDocument (enum): Whether to return the document before or after
* the update is applied. Must be either RETURN_DOCUMENT_BEFORE or
* RETURN_DOCUMENT_AFTER. The default is RETURN_DOCUMENT_BEFORE.
*
* * sort (document): Determines which document the operation modifies if
* the query selects multiple documents.
*
* * upsert (boolean): When true, a new document is created if no document
* matches the query. The default is false.
*
* @param string $databaseName Database name
* @param string $collectionName Collection name
* @param array|object $filter Query by which to filter documents
* @param array|object $update Update to apply to the matched document
* @param array $options Command options
* @throws InvalidArgumentException
*/
public
function
__construct
(
$databaseName
,
$collectionName
,
$filter
,
$update
,
array
$options
=
array
())
{
if
(
!
is_array
(
$filter
)
&&
!
is_object
(
$filter
))
{
throw
new
InvalidArgumentTypeException
(
'$filter'
,
$filter
,
'array or object'
);
}
if
(
!
is_array
(
$update
)
&&
!
is_object
(
$update
))
{
throw
new
InvalidArgumentTypeException
(
'$update'
,
$update
,
'array or object'
);
}
if
(
!
\MongoDB\is_first_key_operator
(
$update
))
{
throw
new
InvalidArgumentException
(
'First key in $update argument is not an update operator'
);
}
$options
+=
array
(
'returnDocument'
=>
self
::
RETURN_DOCUMENT_BEFORE
,
'upsert'
=>
false
,
);
if
(
isset
(
$options
[
'maxTimeMS'
])
&&
!
is_integer
(
$options
[
'maxTimeMS'
]))
{
throw
new
InvalidArgumentTypeException
(
'"maxTimeMS" option'
,
$options
[
'maxTimeMS'
],
'integer'
);
}
if
(
isset
(
$options
[
'projection'
])
&&
!
is_array
(
$options
[
'projection'
])
&&
!
is_object
(
$options
[
'projection'
]))
{
throw
new
InvalidArgumentTypeException
(
'"projection" option'
,
$options
[
'projection'
],
'array or object'
);
}
if
(
!
is_integer
(
$options
[
'returnDocument'
]))
{
throw
new
InvalidArgumentTypeException
(
'"returnDocument" option'
,
$options
[
'returnDocument'
],
'integer'
);
}
if
(
$options
[
'returnDocument'
]
!==
self
::
RETURN_DOCUMENT_AFTER
&&
$options
[
'returnDocument'
]
!==
self
::
RETURN_DOCUMENT_BEFORE
)
{
throw
new
InvalidArgumentException
(
'Invalid value for "returnDocument" option: '
.
$options
[
'returnDocument'
]);
}
if
(
isset
(
$options
[
'sort'
])
&&
!
is_array
(
$options
[
'sort'
])
&&
!
is_object
(
$options
[
'sort'
]))
{
throw
new
InvalidArgumentTypeException
(
'"sort" option'
,
$options
[
'sort'
],
'array or object'
);
}
if
(
!
is_bool
(
$options
[
'upsert'
]))
{
throw
new
InvalidArgumentTypeException
(
'"upsert" option'
,
$options
[
'upsert'
],
'boolean'
);
}
$this
->
findAndModify
=
new
FindAndModify
(
$databaseName
,
$collectionName
,
array
(
'fields'
=>
isset
(
$options
[
'projection'
])
?
$options
[
'projection'
]
:
null
,
'maxTimeMS'
=>
isset
(
$options
[
'maxTimeMS'
])
?
$options
[
'maxTimeMS'
]
:
null
,
'new'
=>
$options
[
'returnDocument'
]
===
self
::
RETURN_DOCUMENT_AFTER
,
'query'
=>
$filter
,
'sort'
=>
isset
(
$options
[
'sort'
])
?
$options
[
'sort'
]
:
null
,
'update'
=>
$update
,
'upsert'
=>
$options
[
'upsert'
],
)
);
}
/**
* Execute the operation.
*
* @see Executable::execute()
* @param Server $server
* @return array|null
*/
public
function
execute
(
Server
$server
)
{
return
$this
->
findAndModify
->
execute
(
$server
);
}
}
tests/Collection/CrudSpec/FindOneAndReplaceFunctionalTest.php
View file @
02e651cb
...
...
@@ -3,6 +3,7 @@
namespace
MongoDB\Tests\Collection\CrudSpec
;
use
MongoDB\Collection
;
use
MongoDB\Operation\FindOneAndReplace
;
/**
* CRUD spec functional tests for findOneAndReplace().
...
...
@@ -46,7 +47,7 @@ class FindOneAndReplaceFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndReplace
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndReplace
(
$filter
,
$replacement
,
$options
);
...
...
@@ -89,7 +90,7 @@ class FindOneAndReplaceFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndReplace
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndReplace
(
$filter
,
$replacement
,
$options
);
...
...
@@ -156,7 +157,7 @@ class FindOneAndReplaceFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndReplace
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndReplace
(
$filter
,
$replacement
,
$options
);
...
...
@@ -179,7 +180,7 @@ class FindOneAndReplaceFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndReplace
::
RETURN_DOCUMENT
_AFTER
,
'upsert'
=>
true
,
);
...
...
tests/Collection/CrudSpec/FindOneAndUpdateFunctionalTest.php
View file @
02e651cb
...
...
@@ -3,6 +3,7 @@
namespace
MongoDB\Tests\Collection\CrudSpec
;
use
MongoDB\Collection
;
use
MongoDB\Operation\FindOneAndUpdate
;
/**
* CRUD spec functional tests for findOneAndUpdate().
...
...
@@ -46,7 +47,7 @@ class FindOneAndUpdateFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndUpdate
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndUpdate
(
$filter
,
$update
,
$options
);
...
...
@@ -89,7 +90,7 @@ class FindOneAndUpdateFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndUpdate
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndUpdate
(
$filter
,
$update
,
$options
);
...
...
@@ -155,7 +156,7 @@ class FindOneAndUpdateFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndUpdate
::
RETURN_DOCUMENT
_AFTER
,
);
$document
=
$this
->
collection
->
findOneAndUpdate
(
$filter
,
$update
,
$options
);
...
...
@@ -177,7 +178,7 @@ class FindOneAndUpdateFunctionalTest extends FunctionalTestCase
$options
=
array
(
'projection'
=>
array
(
'x'
=>
1
,
'_id'
=>
0
),
'sort'
=>
array
(
'x'
=>
1
),
'returnDocument'
=>
Collection
::
FIND_ONE_AND_RETURN
_AFTER
,
'returnDocument'
=>
FindOneAndUpdate
::
RETURN_DOCUMENT
_AFTER
,
'upsert'
=>
true
,
);
...
...
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