Skip to content
This repository has been archived by the owner on Feb 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #846
Browse files Browse the repository at this point in the history
  • Loading branch information
jmikola committed Apr 23, 2015
2 parents 58c2081 + f78ba16 commit 072e324
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 14 deletions.
38 changes: 24 additions & 14 deletions collection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,13 +1400,14 @@ PHP_METHOD(MongoCollection, findOne)
Atomically update and return a document */
PHP_METHOD(MongoCollection, findAndModify)
{
zval *query, *update = 0, *fields = 0, *options = 0;
HashTable *query = NULL, *update = NULL, *fields = NULL;
zval *zquery = NULL, *zupdate = NULL, *zfields = NULL, *options = NULL;
zval *cmd, *retval, **values;
mongo_connection *used_connection;
mongo_collection *c;
mongo_db *db;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!|a!a!a!", &query, &update, &fields, &options) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H!|H!H!a!", &query, &update, &fields, &options) == FAILURE) {
return;
}

Expand All @@ -1421,18 +1422,27 @@ PHP_METHOD(MongoCollection, findAndModify)
add_assoc_zval(cmd, "findandmodify", c->name);
zval_add_ref(&c->name);

if (query && zend_hash_num_elements(Z_ARRVAL_P(query)) > 0) {
add_assoc_zval(cmd, "query", query);
zval_add_ref(&query);
if (query && zend_hash_num_elements(query) > 0) {
MAKE_STD_ZVAL(zquery);
array_init(zquery);
zend_hash_copy(HASH_P(zquery), query, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
add_assoc_zval(cmd, "query", zquery);
}
if (update && zend_hash_num_elements(Z_ARRVAL_P(update)) > 0) {
add_assoc_zval(cmd, "update", update);
zval_add_ref(&update);

if (update && zend_hash_num_elements(update) > 0) {
MAKE_STD_ZVAL(zupdate);
array_init(zupdate);
zend_hash_copy(HASH_P(zupdate), update, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
add_assoc_zval(cmd, "update", zupdate);
}
if (fields && zend_hash_num_elements(Z_ARRVAL_P(fields)) > 0) {
add_assoc_zval(cmd, "fields", fields);
zval_add_ref(&fields);

if (fields && zend_hash_num_elements(fields) > 0) {
MAKE_STD_ZVAL(zfields);
array_init(zfields);
zend_hash_copy(HASH_P(zfields), fields, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
add_assoc_zval(cmd, "fields", zfields);
}

if (options && zend_hash_num_elements(Z_ARRVAL_P(options)) > 0) {
zval *temp;
zend_hash_merge(HASH_P(cmd), HASH_P(options), (void (*)(void*))zval_add_ref, &temp, sizeof(zval*), 1);
Expand Down Expand Up @@ -3064,9 +3074,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_find_one, 0, ZEND_RETURN_VALUE, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_findandmodify, 0, ZEND_RETURN_VALUE, 1)
ZEND_ARG_ARRAY_INFO(0, query, 1)
ZEND_ARG_ARRAY_INFO(0, update, 1)
ZEND_ARG_ARRAY_INFO(0, fields, 1)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, update)
ZEND_ARG_INFO(0, fields)
ZEND_ARG_ARRAY_INFO(0, options, 1)
ZEND_END_ARG_INFO()

Expand Down
75 changes: 75 additions & 0 deletions tests/generic/mongocollection-findandmodify_error-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
--TEST--
MongoCollection::findAndModify() requires query, update, and fields to be a hash
--SKIPIF--
<?php require_once "tests/utils/standalone.inc"; ?>
--FILE--
<?php require_once "tests/utils/server.inc"; ?>
<?php

$host = MongoShellServer::getStandaloneInfo();
$m = new MongoClient($host);
$c = $m->selectCollection(dbname(), collname(__FILE__));
$c->drop();

$c->insert(array('x' => 1));

$document = $c->findAndModify(
array('x' => 1),
array('$inc' => array('x' => 1)),
array('x' => 1),
array('new' => true)
);

printf("Set x to %d\n", $document['x']);

$document = $c->findAndModify(
(object) array('x' => 2),
(object) array('$inc' => array('x' => 1)),
(object) array('x' => 1),
array('new' => true)
);

printf("Set x to %d\n", $document['x']);

$document = $c->findAndModify(
1,
array('$inc' => array('x' => 1)),
array('x' => 1),
array('new' => true)
);

var_dump($document);

$document = $c->findAndModify(
array('x' => 3),
true,
array('x' => 1),
array('new' => true)
);

var_dump($document);

$document = $c->findAndModify(
array('x' => 3),
array('$inc' => array('x' => 1)),
'foo',
array('new' => true)
);

var_dump($document);

?>
===DONE===
--EXPECTF--
Set x to 2
Set x to 3

Warning: MongoCollection::findAndModify() expects parameter 1 to be array, integer given in %s on line %d
NULL

Warning: MongoCollection::findAndModify() expects parameter 2 to be array, boolean given in %s on line %d
NULL

Warning: MongoCollection::findAndModify() expects parameter 3 to be array, string given in %s on line %d
NULL
===DONE===

0 comments on commit 072e324

Please sign in to comment.