Skip to content

Commit 9458df3

Browse files
committed
Merge pull request #119
2 parents 490403a + 31661a3 commit 9458df3

21 files changed

+281
-94
lines changed

config.m4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ if test "$MONGODB" != "no"; then
217217
bson-timegm.c \
218218
bson-utf8.c \
219219
bson-value.c \
220-
bson-version.c \
220+
bson-version-functions.c \
221221
bson-writer.c
222222
";
223223
MONGOC_SOURCES="\
@@ -265,6 +265,7 @@ if test "$MONGODB" != "no"; then
265265
mongoc-topology-description.c \
266266
mongoc-uri.c \
267267
mongoc-util.c \
268+
mongoc-version-functions.c \
268269
mongoc-write-command.c \
269270
mongoc-write-concern.c
270271
";

config.w32

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ if (PHP_MONGODB != "no") {
1313
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "Exception.c LogicException.c RuntimeException.c UnexpectedValueException.c InvalidArgumentException.c ConnectionException.c AuthenticationException.c SSLConnectionException.c DuplicateKeyException.c ExecutionTimeoutException.c ConnectionTimeoutException.c WriteException.c WriteConcernException.c BulkWriteException.c", "mongodb");
1414
ADD_SOURCES(configure_module_dirname + "/src/contrib/", "php-ssl.c", "mongodb");
1515
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/yajl", "yajl_version.c yajl.c yajl_encode.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_tree.c yajl_alloc.c yajl_gen.c", "mongodb");
16-
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", "bcon.c bson.c bson-atomic.c bson-clock.c bson-context.c bson-error.c bson-iter.c bson-iso8601.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version.c bson-writer.c", "mongodb");
17-
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-b64.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-collection.c mongoc-counters.c mongoc-cursor.c mongoc-cursor-array.c mongoc-cursor-transform.c mongoc-cursor-cursorid.c mongoc-database.c mongoc-init.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-page.c mongoc-gridfs-file-list.c mongoc-host-list.c mongoc-index.c mongoc-list.c mongoc-log.c mongoc-matcher-op.c mongoc-matcher.c mongoc-opcode.c mongoc-queue.c mongoc-read-prefs.c mongoc-rpc.c mongoc-set.c mongoc-server-description.c mongoc-socket.c mongoc-stream.c mongoc-stream-buffered.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-topology.c mongoc-topology-scanner.c mongoc-topology-description.c mongoc-uri.c mongoc-util.c mongoc-write-command.c mongoc-write-concern.c", "mongodb");
16+
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", "bcon.c bson.c bson-atomic.c bson-clock.c bson-context.c bson-error.c bson-iter.c bson-iso8601.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c", "mongodb");
17+
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-b64.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-collection.c mongoc-counters.c mongoc-cursor.c mongoc-cursor-array.c mongoc-cursor-transform.c mongoc-cursor-cursorid.c mongoc-database.c mongoc-init.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-page.c mongoc-gridfs-file-list.c mongoc-host-list.c mongoc-index.c mongoc-list.c mongoc-log.c mongoc-matcher-op.c mongoc-matcher.c mongoc-opcode.c mongoc-queue.c mongoc-read-prefs.c mongoc-rpc.c mongoc-set.c mongoc-server-description.c mongoc-socket.c mongoc-stream.c mongoc-stream-buffered.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-topology.c mongoc-topology-scanner.c mongoc-topology-description.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c", "mongodb");
1818
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-rand.c mongoc-scram.c mongoc-stream-tls.c mongoc-ssl.c", "mongodb");
1919
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-sasl.c", "mongodb");
2020

php_phongo.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,10 @@ php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, mongoc_wri
512512
SCP(nRemoved);
513513
SCP(nUpserted);
514514

515-
bson_copy_to(&write_result->upserted, &writeresult->write_result.upserted);
516-
bson_copy_to(&write_result->writeConcernError, &writeresult->write_result.writeConcernError);
517-
bson_copy_to(&write_result->writeErrors, &writeresult->write_result.writeErrors);
515+
bson_copy_to(&write_result->upserted, &writeresult->write_result.upserted);
516+
SCP(n_writeConcernErrors);
517+
bson_copy_to(&write_result->writeConcernErrors, &writeresult->write_result.writeConcernErrors);
518+
bson_copy_to(&write_result->writeErrors, &writeresult->write_result.writeErrors);
518519
SCP(upsert_append_count);
519520
#undef SCP
520521

@@ -684,10 +685,7 @@ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc
684685
/* The Write failed */
685686
if (!success) {
686687
/* The Command itself failed */
687-
if (
688-
bson_empty0(&writeresult->write_result.writeErrors)
689-
&& bson_empty0(&writeresult->write_result.writeConcernError)
690-
) {
688+
if (bson_empty0(&writeresult->write_result.writeErrors) && bson_empty0(&writeresult->write_result.writeConcernErrors)) {
691689
/* FIXME: Maybe we can look at write_result.error and not pass error at all? */
692690
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
693691
} else {
@@ -726,7 +724,9 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, const p
726724
return false;
727725
}
728726

729-
cursor->hint = server_id;
727+
if (server_id > 0) {
728+
cursor->hint = server_id;
729+
}
730730
if (!mongoc_cursor_next(cursor, &doc)) {
731731
bson_error_t error;
732732

@@ -757,7 +757,9 @@ int phongo_execute_command(mongoc_client_t *client, const char *db, const bson_t
757757

758758

759759
cursor = mongoc_client_command(client, db, MONGOC_QUERY_NONE, 0, 1, 0, command, NULL, read_preference);
760-
cursor->hint = server_id;
760+
if (server_id > 0) {
761+
cursor->hint = server_id;
762+
}
761763

762764
if (!mongoc_cursor_next(cursor, &doc)) {
763765
bson_error_t error;
@@ -821,7 +823,11 @@ void phongo_stream_destroy(mongoc_stream_t *stream_wrap) /* {{{ */
821823
{
822824
php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream_wrap;
823825

824-
MONGOC_DEBUG("Not destroying RSRC#%d", base_stream->stream->rsrc_id);
826+
if (base_stream->stream) {
827+
MONGOC_DEBUG("Not destroying RSRC#%d", base_stream->stream->rsrc_id);
828+
} else {
829+
MONGOC_DEBUG("Wrapped stream already destroyed");
830+
}
825831
/*
826832
* DON'T DO ANYTHING TO THE INTERNAL base_stream->stream
827833
* The stream should not be closed during normal dtor -- as we want it to
@@ -851,7 +857,14 @@ int phongo_stream_close(mongoc_stream_t *stream_wrap) /* {{{ */
851857
php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream_wrap;
852858

853859
MONGOC_DEBUG("Closing RSRC#%d", base_stream->stream->rsrc_id);
854-
phongo_stream_destroy(stream_wrap);
860+
if (base_stream->stream) {
861+
TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls);
862+
863+
MONGOC_DEBUG("Destroying RSRC#%d", base_stream->stream->rsrc_id);
864+
php_stream_free(base_stream->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR);
865+
base_stream->stream = NULL;
866+
}
867+
855868
return 0;
856869
} /* }}} */
857870

@@ -2007,25 +2020,30 @@ bool php_phongo_writeresult_get_write_errors(php_phongo_writeresult_t *writeresu
20072020
}
20082021
return false;
20092022
} /* }}} */
2023+
20102024
bool php_phongo_writeresult_get_writeconcern_error(php_phongo_writeresult_t *writeresult, bson_error_t *error) /* {{{ */
20112025
{
20122026
const char *err = NULL;
20132027
uint32_t code = 0;
2028+
bson_iter_t iter;
2029+
bson_iter_t citer;
20142030

2015-
if (!bson_empty0(&writeresult->write_result.writeConcernError)) {
2016-
bson_iter_t iter;
2017-
2018-
if (bson_iter_init_find(&iter, &writeresult->write_result.writeConcernError, "code") && BSON_ITER_HOLDS_INT32(&iter)) {
2019-
code = bson_iter_int32(&iter);
2020-
}
2021-
if (bson_iter_init_find(&iter, &writeresult->write_result.writeConcernError, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) {
2022-
err = bson_iter_utf8(&iter, NULL);
2031+
if (!bson_empty0 (&writeresult->write_result.writeConcernErrors) &&
2032+
bson_iter_init (&iter, &writeresult->write_result.writeConcernErrors) &&
2033+
bson_iter_next (&iter) &&
2034+
BSON_ITER_HOLDS_DOCUMENT (&iter) &&
2035+
bson_iter_recurse (&iter, &citer)) {
2036+
while (bson_iter_next (&citer)) {
2037+
if (BSON_ITER_IS_KEY (&citer, "errmsg")) {
2038+
err = bson_iter_utf8 (&citer, NULL);
2039+
} else if (BSON_ITER_IS_KEY (&citer, "code")) {
2040+
code = bson_iter_int32 (&citer);
2041+
}
20232042
}
20242043

20252044
bson_set_error(error, PHONGO_ERROR_WRITECONCERN_FAILED, code, "%s", err);
20262045
return true;
20272046
}
2028-
20292047
return false;
20302048
} /* }}} */
20312049
zval* php_phongo_throw_write_errors(php_phongo_writeresult_t *wr TSRMLS_DC) /* {{{ */

src/MongoDB/WriteResult.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,33 @@ PHP_METHOD(WriteResult, getWriteConcernError)
250250
}
251251

252252

253-
if (!bson_empty0(&intern->write_result.writeConcernError)) {
254-
object_init_ex(return_value, php_phongo_writeconcernerror_ce);
255-
if (!phongo_writeconcernerror_init(return_value, &intern->write_result.writeConcernError TSRMLS_CC)) {
256-
zval_ptr_dtor(&return_value);
253+
if (!bson_empty0(&intern->write_result.writeConcernErrors)) {
254+
bson_iter_t iter;
255+
256+
bson_iter_init(&iter, &intern->write_result.writeConcernErrors);
257+
258+
while (bson_iter_next(&iter)) {
259+
bson_t cbson;
260+
uint32_t len;
261+
const uint8_t *data;
262+
263+
if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
264+
continue;
265+
}
266+
267+
bson_iter_document(&iter, &len, &data);
268+
269+
if (!bson_init_static(&cbson, data, len)) {
270+
continue;
271+
}
272+
273+
object_init_ex(return_value, php_phongo_writeconcernerror_ce);
274+
275+
if (!phongo_writeconcernerror_init(return_value, &cbson TSRMLS_CC)) {
276+
zval_ptr_dtor(&return_value);
277+
}
278+
279+
return;
257280
}
258281
}
259282
}
@@ -429,6 +452,7 @@ HashTable *php_phongo_writeresult_get_debug_info(zval *object, int *is_temp TSRM
429452
php_phongo_writeresult_t *intern;
430453
zval retval = zval_used_for_init;
431454
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
455+
bson_iter_t iter;
432456

433457
intern = (php_phongo_writeresult_t *)zend_object_store_get_object(object TSRMLS_CC);
434458
*is_temp = 1;
@@ -456,10 +480,21 @@ HashTable *php_phongo_writeresult_get_debug_info(zval *object, int *is_temp TSRM
456480
bson_to_zval(bson_get_data(&intern->write_result.writeErrors), intern->write_result.writeErrors.len, &state);
457481
add_assoc_zval_ex(&retval, ZEND_STRS("writeErrors"), state.zchild);
458482

483+
if (!bson_empty0(&intern->write_result.writeConcernErrors) &&
484+
bson_iter_init(&iter, &intern->write_result.writeConcernErrors) &&
485+
bson_iter_next(&iter) &&
486+
BSON_ITER_HOLDS_DOCUMENT(&iter)) {
487+
uint32_t len;
488+
const uint8_t *data;
459489

460-
MAKE_STD_ZVAL(state.zchild);
461-
bson_to_zval(bson_get_data(&intern->write_result.writeConcernError), intern->write_result.writeConcernError.len, &state);
462-
add_assoc_zval_ex(&retval, ZEND_STRS("writeConcernError"), state.zchild);
490+
bson_iter_document(&iter, &len, &data);
491+
492+
MAKE_STD_ZVAL(state.zchild);
493+
bson_to_zval(data, len, &state);
494+
add_assoc_zval_ex(&retval, ZEND_STRS("writeConcernError"), state.zchild);
495+
} else {
496+
add_assoc_null_ex(&retval, ZEND_STRS("writeConcernError"));
497+
}
463498

464499
if (intern->write_concern) {
465500
zval *write_concern = NULL;

src/libmongoc

Submodule libmongoc updated 114 files
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
Connect to MongoDB with using X509 retrieving username from certificate #002
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; NEEDS("STANDALONE_X509"); ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
function connect($dsn, $opts) {
10+
try {
11+
$manager = new MongoDB\Driver\Manager($dsn, array(), $opts);
12+
13+
$bulk = new MongoDB\Driver\BulkWrite();
14+
$bulk->insert(array("very" => "important"));
15+
$manager->executeBulkWrite(NS, $bulk);
16+
echo "Connected\n";
17+
} catch(Exception $e) {
18+
echo get_class($e), ": ", $e->getMessage(), "\n";
19+
}
20+
return $manager;
21+
22+
}
23+
$SSL_DIR = realpath(__DIR__ . "/" . "./../../scripts/ssl/");
24+
25+
$opts = array(
26+
"peer_name" => "server",
27+
"verify_peer" => true,
28+
"verify_peer_name" => true,
29+
"allow_self_signed" => false,
30+
"cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */
31+
"capath" => $SSL_DIR, /* Defaults to openssl.capath */
32+
"local_cert" => $SSL_DIR . "/src/libmongoc/tests/certificates/client.pem",
33+
);
34+
$parsed = parse_url(STANDALONE_X509);
35+
$dsn = sprintf("mongodb://username@%s:%d/%s?ssl=true&authMechanism=MONGODB-X509", $parsed["host"], $parsed["port"], DATABASE_NAME);
36+
37+
38+
$m1 = connect($dsn, $opts);
39+
$m2 = connect($dsn, $opts);
40+
41+
echo "Both should have failed with auth failure - without reusing previous stream\n";
42+
?>
43+
===DONE===
44+
<?php exit(0); ?>
45+
--EXPECTF--
46+
MongoDB\Driver\Exception\AuthenticationException: auth failed
47+
MongoDB\Driver\Exception\AuthenticationException: auth failed
48+
Both should have failed with auth failure - without reusing previous stream
49+
===DONE===
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::executeDelete() write error
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(STANDALONE);
10+
11+
$manager->executeInsert(NS, ['x' => 1]);
12+
13+
echo throws(function() use ($manager) {
14+
$manager->executeDelete(NS, ['$foo' => 1], ['limit' => 1]);
15+
}, 'MongoDB\Driver\Exception\WriteException'), "\n";
16+
17+
?>
18+
===DONE===
19+
<?php exit(0); ?>
20+
--EXPECT--
21+
OK: Got MongoDB\Driver\Exception\WriteException
22+
unknown top level operator: $foo
23+
===DONE===
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::executeDelete() write concern error
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php NEEDS("REPLICASET"); CLEANUP(REPLICASET); ?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . "/../utils/basic.inc";
9+
10+
$manager = new MongoDB\Driver\Manager(REPLICASET);
11+
12+
$manager->executeInsert(NS, ['x' => 1]);
13+
14+
echo throws(function() use ($manager) {
15+
$manager->executeDelete(NS, ['x' => 1], ['limit' => 1], new MongoDB\Driver\WriteConcern(30));
16+
}, 'MongoDB\Driver\Exception\WriteConcernException'), "\n";
17+
18+
?>
19+
===DONE===
20+
<?php exit(0); ?>
21+
--EXPECT--
22+
OK: Got MongoDB\Driver\Exception\WriteConcernException
23+
Not enough data-bearing nodes
24+
===DONE===
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::executeInsert() write error
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(STANDALONE);
10+
11+
echo throws(function() use ($manager) {
12+
$manager->executeInsert(NS, ['$foo' => 1]);
13+
}, 'MongoDB\Driver\Exception\WriteException'), "\n";
14+
15+
?>
16+
===DONE===
17+
<?php exit(0); ?>
18+
--EXPECT--
19+
OK: Got MongoDB\Driver\Exception\WriteException
20+
Document can't have $ prefixed field names: $foo
21+
===DONE===

0 commit comments

Comments
 (0)